一面
-
关于稀疏网络的理解?group lasso知道吗?
-
为什么sigmoid函数可以表示概率?其他可以归一化的函数可以用来表示概率吗?(广义线性表)
-
推导一下交叉熵loss
-
写题
给定一个乱序正数数组,判断是否可以平分成两个部分
Sample1:
input: 1,3,6,2,5,3
output: true
Sample2:
input: 2,5,7,8,2,1
output: false
解题思路:用递归或者DFS或者动规都可以解决,且代码比较简洁。面试时想到的使用BFS来做,代码没有写完整。通常来说,BFS和DFS都可以解决时,优先选DFS的代码,因为写起来会简单一些。
bool is_equal_apart(vector<int> arr, int s, int target) {
int len = arr.size();
for (int i = s; i < len; i++) {
if (arr[i] == target) return true;
if (arr[i] > target) break;
if (is_equal_apart(arr, i + 1, target - arr[i])) return true;
}
return false;
}
二面
- 简单聊项目
- 写题
给定一个乱序数组
a: [-1, 3, 5, 2, 3, 1, 6, 7]
再给定一个排序的索引数组
b: [2, 4, 5, 8]
要求返回a中绝对值比b小的数的个数
最优时间复杂度O(n),空间复杂度O(1)
面试时首先想到用哈希表来做,需要额外的空间;然后想到遍历a,将绝对值比b中元素小的对应结果++,这里仍然需要每次遍历b,没有充分利用b数组的递增特性。进一步优化是每次在求b中下一个索引对应的结果时,在上一步的基础上进行。当然前提是需要对a进行排序。
这里还有一个边界时b中有多个值比a中最大一个元素大时,会出现b中元素没计算完的情况,这时需要做一个赋值运算。
注意:溢出边界和特殊边界需要处理。然后就是b没有被算完的情况,这时赋值不要用下面注释的方式,会出错。
vector<int> count_by_index(vector<int> a, vector<int> b) {
int len_a = a.size();
int len_b = b.size();
if (!len_a || !len_b) return vector<int>();
vector<int> res = vector<int>(len_b, 0);
for (int i = 0; i < len_a; i++) a[i] = abs(a[i]);
sort(a.begin(), a.end());
int i = 0, j = 0;
while (i < len_a) {
if (a[i] <= b[j]) {
res[j]++;
i++;
}else {
if (j + 1 < len_b) { //第一次微软面试就挂在这样的边界上~~~
res[j + 1] = res[j];
j++;
}
}
}
//if (j < len_b && j - 1 >= 0) res[j++] = res[j - 1];// 这样写很容易错,因为无法判断最后一次j有没有执行j++
for (int i = 0; i < len_b; i++) {
if (!res[i] && i >= 1) res[i] = res[i - 1];
}
return res;
}
整体来说,面试写的题并不难,但写得并不好,总结就是:题刷得不够,总结不够,边界考虑不够仔细。最重要的事,思路不够清晰,平时在做题时也会有这个问题,常常是没有完全想清楚就开始写,一边写一边整理思路,这个在面试中往往时是不好的,这方面在只有的训练中需要特别加强一下。