三本的我面试微软,微软包机票酒店早餐到苏州,实在太棒了

2019苏州微软面经

简介,苏州微软,目前已经电话三轮,全过,过了后可以公费去苏州现场面试。

比国外 Google的面试难度要低一些,或者说,偏重点更不一样。

微软你可以只做一道面试题,思路清晰,完整,边界情况考虑清楚,代码写好就行了。

但是 Google 是需要你在 40 分钟内,完美答出两道题目,这就是区别。

另外,苏州微软是用中文的,也是容易了一些的原因——因为用英语你确实脑子转不过来。

第一轮

没有给出题目,口头说的,我整理一下:

判断一个数组是否基本有序,其实就是可否通过一次简单的交换就满足有序。

例子:

  • 1, 2, 3, 6, 5, 12 是基本有序数组,因为可以交换 6 跟 5, 变成1, 2, 3, 5, 6, 12
  • 1, 5, 4, 3, 6 也是基本有序数组,可以交换 5 跟 3
  • 3,2, 1, 0 就不是基本有序数组了,因为你交换一次数组并不能使此数组有序。

思路不难,仔细分析一下,有序的数组数字关系是这样: a < b < c < d < e,而基本有序则是:a < b > c > d <e,这样可能不好看,简单来说就是那两个数字在是不满足x < y的关系的。

可以遍历此数组,只要有多于一个数字是比两边都要大,且有一个数字是比左右两边要小的,那就是基本有序数组,其余的都不是。当然,你也要考虑本来这个数组就是有序的情况。

在面试时写的代码与交流草稿如下,这份代码是不能当答案看的,只是让朋友你们看看怎么样的代码可以过面试。建议你们自己写写可以编译过的代码。

int array
1, 2,  3, 6, 5, 12 true
       i
       min: 3, miax: 5

1, 5, 4, 3, 6

sub array -> reverse -> true

1, 2, 3, 6, _5,

1, 5, 4, 3, 6
max: 5
min: 3
1 < min < max < least
   i,

   1, 5, 4, 2,  8, 19, 7, 12

   5, 4, 9
   min: 2
   max: 5

   sub array -> sorted?
   7
   3

i: 2,

    1, 2, 3, 8, 7, 6 ,5,  12

bool is_almost_sorted_array(vector<int> a) {
    int mem_l;
    bool flag = false;
    int l_idx = -1, r_idx = -1;
    On(m sub_arry)
    for(int i=0; i<a.size()-1; i++) {
        // sub array
        if(a[i] > a[i+1]) {
            int mem_l = i;
            int sub_min = a[mem_l];
            if(mem_l+1 < a.size())
                sub_min = a[mem_l+1];
            while(i<a.size() && a[i] > a[i+1]) {
                if(flag == true) return false;
                i++;
            }
            /* 1, 2, 7, 4, 5, 6, 3, 8 */
            /* i: 3, ->,
             * i: 6,
             * */
            int sub_max = a[i-1];
            if(l_idx == -1 && i - mem_l == 1) {//only one
                l_idx = i-1;
            }else if(r_idx == -1 && i - mem_l == 1) {
                r_idx = i;
                if(a[r_idx] > a[l_idx-1] && a[r_idx] < a[l_idx+1]  &&
                   a[l_idx] > a[r_idx-1] && (r_idx == a.size() || a[l_idx] < a[r_idx+1]))
                    flag = true;
                else
                    return false;
            }else{
                flag = true; //Have Changed Once
                if(sub_min <= a[mem_l] || i == a.size() || sub_max >= a[i])
                    return false;
            }
        }
    }
    return true;
}
test case:
1, 2, 3 =>
3, 2, 1 =>
i:0, a[0]>a[1], mem_l:0, sub_min: 2, subm: 3
i:1, sub_min: a[2] vs 3,        1          3
i:2,
    1 >= 1, 3 >=

面试反馈就是对 边界情况考虑不周全,可以多加强。(是的,如上的一些判断语句是跟面试官一起过了一遍才加上的)。

第二轮

第二轮面试官是贴了题目,顺道解释了一下,在这里锻炼你们的英语能力,我就不给你们解释了。

Split a string into sub-strings. Each sub-string should be no longer than the given limit. The input string contains English letters and spaces only. 
Do not break a word into two sub strings. Remove all spaces in the beginning or end of every sub string.

Extend: append notation such as " (1 of 12)" and strings are not longer than the limit even after the notation.

Length limit: 39. Input: The quick brown fox jumps over a lazy dogThe quick brown fox jumps over a lazy dogThe quick brown fox jumps over a lazy dogThe quick brown fox jumps over a lazy dogThe quick brown fox jumps over a lazy dogThe quick brown fox jumps over a lazy dogThe quick brown fox jumps over a lazy dogThe quick brown fox jumps over a lazy dogThe quick brown fox jumps over a lazy dog

Result should be:
The quick brown fox jumps (1 of 14)
over a lazy dogThe quick (2 of 14)
brown fox jumps over a lazy (3 of 14)
dogThe quick brown fox jumps (4 of 14)
over a lazy dogThe quick (5 of 14)
brown fox jumps over a lazy (6 of 14)
dogThe quick brown fox jumps (7 of 14)
over a lazy dogThe quick (8 of 14)
brown fox jumps over a lazy (9 of 14)
dogThe quick brown fox jumps (10 of 14)
over a lazy dogThe quick (11 of 14)
brown fox jumps over a lazy (12 of 14)
dogThe quick brown fox jumps (13 of 14)
over a lazy dog (14 of 14)

这题我没有正确的思路,因为现在我还没有想出最优解,也没有在网上找到类似的题目,有看过的同学可以分享一下。难点就是,在插入每行附加信息的同时,又不能让这行的字数超出。

我是这样子做的:

每行先不插入信息,先正常的换行,换行完毕后,再递归去插入信息——因为插入信息后会因为行数进位而又需要调整一遍,如 99 变成 100.

我写出的代码如下:

vector<string> split_sub_strings(string input, int limit) {
    vector<string> res;
    int count = 0;
    for(int i=0; i<input.length(); ++i) {
        int mem_i = i;
        string current_line = "";
        while(input[i] != ' ') {
            i++;
        }
        int word_len = i - mem_i;
        //可以容纳下个词不 
        if(res[count].length() + word_len> limit) {
            res.push_back(current_line);
            count++;
            continue;
        }else {
            current_line += input.splice(mem_i, i);
        }
         while(input[i] == ' ') {
            i++;
        }
    }
    return update_info(res, limit, count);
}

string get_apend_info(int cnt, int sum) {
     return "(" + to_string(cnt) + " of " to_string(sum) + ")"
}

string retrieve_back_words(string s) {
  st
   for(int i=s.length(); s>0; s--) {
   }
}

// backwords: 
//Len 35 : The quick(1 of 14)

//over a lazy dogThe quick jumps  brown fox            (2 of 14)
// append back workds
vector<string> update_info(vector<string> list_of_lines, int limit, int sum) {
    vector<string> res;
    int cnt = 0;
    string back_words = "";
    

    for(auto line : list_of_lines) {
        string new_line = line + retrieve_back_words(back_words) + get_apend_info(cnt, sum);
        if(new_line.length() > limit){
            for(int i=line.length(); i>0; i--) {
               mem_i = i;
              while(line[i] != ' ') {
                   line--;
               }
               back_words = back_words + line.splice(mem_i, i) + ' ';
               new_line = line.splice(0, i) + get_apend_info(cnt, sum);
               if(new_line.length() < limit) {
                   res.push_back(new_line);
               }
            }
        }
    }
    if(back_words.length == 0) {
        return res;
    }else {
       sum += 1;
       res.push_back(retrieve_back_words(back_words)
       return update_info(res, limit, sum);
    }
}

第三轮

这轮是纯英语面试,美国的友人早晨 7 点打电话来的,对于 9 点起床的我来说,状态不好。

leetcode 原题 https://leetcode.com/problems/min-stack/ ,不过我没有做过。

Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.

  • push(x) -- Push element x onto stack.
  • pop() -- Removes the element on top of the stack.
  • top() -- Get the top element.
  • getMin() -- Retrieve the minimum element in the stack.

Example:

MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --> Returns -3.
minStack.pop();
minStack.top();      --> Returns 0.
minStack.getMin();   --> Returns -2.

开始,或者正常人的想法都是马上想到用一个成员变量来存这个最小值,push 的时候能做到 O1,但是做 pop 的时候发现,这时候不清楚 pop 出去的是不是最小值以及是不是有多个最小值,这时算法就不是 O1 了。

想了一下子后,我就想到利用 slice window(滑动窗口)的思想来做,用数组记录区间值最小值,每次 push 不是比这个数小就不存。

例如: 12,6, 9, 7, 5, 22,29, 1 我会这样子存: 12, 6,5,1

  • 12 无论如何都是要放的,然后 6 比 12 小,存起来;9,7 都不比 6 小,不需要存——之后只要是 9,7 这两个值,返回最小值 6 就行。

  • 然后 5 比 6 小,存起来;22,29 大于 5,不需要存,然后最小值就是之前存起来那个 5 啦。

  • 最后 1 比 5 小,存起来。

简而言之,就是一个最小值列表,存起来当前区间的最小值。

pop 的时候检查一下最小值数组是否是要 pop 的值,维护一下就行,push 跟 pop 都是 O1 了

做的时候我用的是数组,面试完后我查了下,发现可以用抽象程度更高的 stack 来代替数组。因为我一直处理的也是数组的最后一位,跟 stack 的行为一模一样的。

posted @ 2021-02-17 13:07  山尽  阅读(204)  评论(0编辑  收藏  举报