微軟暑期實習面試題

一面

  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;
}

整體來說,面試寫的題並不難,但寫得並不好,總結就是:題刷得不夠,總結不夠,邊界考慮不夠仔細。最重要的事,思路不夠清晰,平時在做題時也會有這個問題,常常是沒有完全想清楚就開始寫,一邊寫一邊整理思路,這個在面試中往往時是不好的,這方面在只有的訓練中需要特別加強一下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章