面试题记录
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;
以上是关于面试题记录的主要内容,如果未能解决你的问题,请参考以下文章