面试题记录

Posted 走过_冬天

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试题记录相关的知识,希望对你有一定的参考价值。

华为面试题:

第1题、给定一个字符串数组,例如[“time”,“me”,“bell”], 然后把字符数据拼接成一个字符串,中间用“#”号键连接,如time#bell#。总长度是10, 字符串解压数组[0,2,5]。(0表示time是 time#bell#从下标0开始到第一个"#“号结束,2表示me是time#bell#从下标2开始到第一个”#"号结束)。只要输出压缩后的长度
输入:[“time”,“me”,“bell”]
输出:10

解题思路:
先分割出单词, 接着筛选字符串,然后拼接,最后计算解压下标数组。时间复杂度O(n^2),空间复杂度O(n)。

代码:

#include <iostream>
#include <vector>
#include <string.h>

using namespace std;

struct word

	string str="";
	int strlen = 0;
	int offset = 0;
	int parent_index = -1;
	int zip_start = 0;
;


void preprocessing(const char str[], vector<word>& vct_words)

	int len = strlen(str);
	int index;

	try 
		char *_str = new char[len];
	
	catch (const bad_alloc& e)
	
		/// TODO
		return ;
	


	bool is_start, is_end;

	is_start = false;
	is_end = false;

	for (int i = 0; i < len; ++i)
	
		if ('\\]' == str[i] || '\\[' == str[i] || '\\,' == str[i])
		
			continue;
		

		if ('\\"' == str[i])
		
			if (is_start)
			
				is_end = true;
			
			else
			
				index = 0;
				is_start = true;
				continue;
			
		

		if (is_end)
		
			word _word;
			_str[index] = '\\0';
			_word.str = _str;
			_word.strlen = index;
			vct_words.push_back(_word);

			index = 0;
			is_start = false;
			is_end = false;
			continue;
		

		_str[index++] = str[i];
	

	delete[] _str;



void select_words(vector<word>& vct_words)

	string sub_str = "";
	size_t size = vct_words.size();
	int i_strlen, j_strlen;

	for (int i = 0; i < size; ++i)
	
		i_strlen = vct_words[i].str.length();

		for (int j = 0; j < size; j++)
		
			j_strlen = vct_words[j].str.length();

			if (i == j || i_strlen >= j_strlen)
			
				continue;
			

			// 截取单词尾部固定长度字符串;
			sub_str = vct_words[j].str.substr(j_strlen - i_strlen, i_strlen);

			if (strcmp(vct_words[i].str.c_str(), sub_str.c_str()) != 0)
			
				continue;
			
			else
			
				vct_words[i].parent_index = j;
				vct_words[i].offset = j_strlen - i_strlen;

				// 更新相关单词的引用下标;
				for (int k = 0; k < i; ++k)
				
					if (vct_words[k].parent_index == i)
					
						vct_words[k].parent_index = j;
						vct_words[k].offset = vct_words[i].offset + vct_words[k].offset;
					
				

				break;
			
		
	


void compress(
	const vector<word>& vct_words,
	vector<int>& vct_index,
	string& zip_string, 
	int& zip_len
)

	size_t size = vct_words.size();
	zip_string = "";
	zip_len = 0;

	if (0 == size) return;

	vct_index.resize(size);

	// 确定压缩字符串及字符串长度;
	vct_index[0] = 0;
	int cur_start = 0;
	for (int i = 0; i < size; ++i)
	
		int par_index = vct_words[i].parent_index;
		vct_index[i] = -1;

		if (par_index != -1) continue;

		zip_string += vct_words[i].str + "#";
		vct_index[i] = zip_len;
		zip_len += vct_words[i].strlen + 1;
	

	// 确定有重叠字符的引用关系;
	for (int i = 0; i < size; ++i)
	
		int par_index = vct_words[i].parent_index;

		if (par_index == -1) continue;

		vct_index[i] = vct_index[par_index] + vct_words[i].offset;
	

 

void display(
	const vector<int>& vct_index,
	const string& zip_string,
	const int& zip_len
)

	cout << zip_len << endl;
	cout << zip_string.c_str() << endl;
	cout << "[ ";
	for each(auto item in vct_index)
	
		cout << item << ", ";
	
	cout << "]" << endl;


int main()

	char str[] = "[\\"time\\", \\"me\\", \\"bell\\"]";
	std::vector<word> vct_words;
	std::vector<int> vct_index;
	string zip_string;
	int zip_len;

	// 字符串分解;
	preprocessing(str, vct_words);

	// 筛选出不重复的字符串;
	select_words(vct_words);

	// 压缩;
	compress(vct_words, vct_index, zip_string, zip_len);

	display(vct_index, zip_string, zip_len);

	return 0;

第一次现场面,现场上机做题,感觉不是很自然,30分钟内没完成,结束的时候面试官问题了一下解题思路,说完我的想法后嘴贱补了一句“我还没有完全想好”然后就gg了。 这道题感觉细节比较多,比方[“time”,“me”,“bell”,“out”,“hout”,“phout”] 和 [“me”,“me”,“time”,“me”,“bell”,“out”,“hout”,“phout”] 这种时候的拼接和处理。面试结束后自己继续完成了这套题,在这里记录一下。不知道有没有更好的解法,如果网友知道更好的方法,欢迎在评论区交流。

第2题、在整形数组中查找连续最长的子数组,使得了数组的和等于给定的目标值k。
输入:[1,-1,5,-2,3] k = 3
输出:[1,-1,5,-2]

解题思路: 用sum[i]存储前i项的和,找出sum[j]-sum[i] = k的项,比较j-i的最大值,时间复杂度O(n^2),空间复杂度O(n)

代码:

#include <iostream>
#include <vector>

using namespace std;
                                                                                                                                                                       

int fun(const vector<int >& arr, int k, int &s, int &e)

	vector<int > arr_sum;
	arr_sum.resize(arr.size());

	size_t size = arr.size();

	int sum = 0;
	for (int i = 0; i < size; ++i)
	
		sum += arr[i];
		arr_sum[i] = sum;
	

	int max_len = -1,len;
	for (int i = 0; i < size; ++i)
	
		if (k == arr_sum[i])
		
			len = e + 1;
			if (len > max_len)
			
				s = 0;
				e = i;
				max_len = len;
			
		

		for (int j = i + 1; j < size; ++j)
		
			if (arr_sum[j] - arr_sum[i] == k)
			
				len = e - s + 1;
				if (len > max_len)
				
					s = i;
					e = j;
					max_len = len;
				
			
		
	

	if (max_len == -1)
	
		return -1;
	
	else
	
		return 0;
	



int main()

	vector<int> arr 1, -1, 5, -2, 3 ;
	int ret, k = 3, e, s;

	ret = fun(arr, k, s, e);

	if (-1 == ret)
	
		cout << 0 << endl;
	
	else
	
		for (int i = s; i <= e; ++i)
		
			cout << arr[i] << " ";
		
		cout << endl;
	

	return 0;

面试官说有时间复杂度O(n)的算法,代码只要10多行。想了一会儿没有想到。网上找了一下第二题,算是一道面试经典题的变式,用哈希表的key存储前i项和,value存储i值,map[sum] = i,表示和为sum的序列为[0,i],假设map[sum-k]的序列为[0,j],那么arr[i ~ j]就是和为sum的连续序列。只要找出[i ~ j]为的最大值序列即可。注意初始化sum_map[0] = -1。

代码:

#include <iostream>
#include <map>

using namespace std;

int main()

	int arr[] =  5, 1, -2, 2, -1, 5, -2, 3 ;
	int k = 0, e, s;

	map<int, int> sum_map;
	int len = sizeof(arr) / sizeof(int);
	
	sum_map[0] = -1;
	int _sum = 0;
	int length = 0;
	for (int i = 0; i < len; ++i)
	
		_sum += arr[i];

		if (sum_map.find(_sum) == sum_map.end())
		
			sum_map[_sum] = i;
		

		if (sum_map.find(_sum - k) != sum_map.end())
		
			if (length < i-sum_map[_sum - k])
			
				length = i - sum_map[_sum - k];
				s = sum_map[_sum - k]+1;
				e = i+1;
			
		
	

	for (int i = s; i < e; ++i)
	
		cout << arr[i] << " ";
	

	cout << endl;

	return 0;

以上是关于面试题记录的主要内容,如果未能解决你的问题,请参考以下文章

记录一次面试中二分查找的算法题

[LeetCode][Python]刷题记录 1. 两数之和

蓝队面试题

JVM10道不得不会的JVM面试题

面试了一个32岁的大佬,明显感觉到他背过很多面试题…

不一样的Java面试题,不一样的感觉.