微软暑期实习面试题

一面

  1. 关于稀疏网络的理解?group lasso知道吗?

  2. 为什么sigmoid函数可以表示概率?其他可以归一化的函数可以用来表示概率吗?(广义线性表)

  3. 推导一下交叉熵loss

  4. 写题
    给定一个乱序正数数组,判断是否可以平分成两个部分
    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;
}

二面

  1. 简单聊项目
  2. 写题
    给定一个乱序数组
    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;
}

整体来说,面试写的题并不难,但写得并不好,总结就是:题刷得不够,总结不够,边界考虑不够仔细。最重要的事,思路不够清晰,平时在做题时也会有这个问题,常常是没有完全想清楚就开始写,一边写一边整理思路,这个在面试中往往时是不好的,这方面在只有的训练中需要特别加强一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值