微软面经

pre

算上15年,本科那次,这已经是第二次微软面试了,可惜两次都没有过,之前是面实习,走到了三面,然后讨论算法的时候没有被认可,被刷了。这次感觉是准备不充分,一面的时候表现的思路太混乱,被reject,二面面试官也没有给我好脸色,然后算法部分没有给出最优算法,果断被刷掉了。

基本过程

笔试

没有太大的难度,编程基本功扎实就能过,很水,不多聊。

一面

一面面试官针对我最近的一次的实习内容做了提问,可能因为很多业务相关,并且面试官对于我那份实习相关的知识并不精通,所以实习背景部分聊的还OK,接下来就是两条笔试题。

第一条是评断平面上一堆点是否在两条直线上,我在思考了一阵之后,还是决定,先选取前三个点,判断是否共线,如果共线,尝试在该直线之外找到一条新的直线,在检查剩下的所有点是否在这两条直线上,如果三点共线,那么我可以确定三条直线,然后假设任何一条是目标直线,然后根据另外一个点尝试构建一条新的直线,然后检查平面上的其他的点。算法复杂度大概是 O(n).。在回答的过程中,我思路有点混乱,在构建直线的时候,忘记考虑x=xi的问题,然后被指了出来,最终修修补补把整个程序怼了出来,看起来面试官还不错,没有因此就直接把我reject了。

第二条是已知一个人的日程表,日程表中有很多任务,每个任务有一个开始和一个结束时间,任务之间可能重叠,这边的时间是一个虚构的概念,时间的值可以任取,范围不做限制。我的第一想法是构建线段树,但是应为时间范围不受控,我放弃了(当然这是一个错误决策,之后会说)。然后我提出了根据任务的开始时间进行排序,然后对于存在重叠时间的任务做合并,也就是构建繁忙时间段,然后根据时间去查询空闲时间,基本的时间是排序的时间复杂度是O(N logN),然后做合并的过程是O(N),最后查询的过程也是O(N)。 当然,我觉得面试官还是不喜欢这个算法, 然后他最后也暗示我了有更有的算法,然后我想起来了离散的线段树,首先将所有的开始时间和结束时间收集起来,然后做排序,根据排序做与index 的映射,然后构建离散线段树,最后构建的过程是Nlog N , 然后查询的过程是LogN。当然线段树是极大程度上减少了查询的时间。感觉还是题目的输入数据没有说清楚,然后构建算法的过程就很迷,我觉得动态插入没有和查询少的情况下,并没有差异。

虽然一面面试官的人比较好,但是我中间讨论的过程的表现并不理想,虽然题目都做出来了,最优或接近最优,但是最后还是毫不留情的给了reject。

二面

二面的面试官应为一面的结果对我开始有一定的偏见,然后对于我的态度并不是那么OK,开始也是询问了实习相关的内容,因为那个实习的过于久远,3年前了毕竟,我中间有些细节记不清了,最后也是被怼。

接下来是一条编程题,题目是给定一个字符串,然后找到最多不超过3个不同字符的子串的最长长度。我一开始的思路错了,我一直想找到DP的数组类似的结果解决,然后我开始构建多遍扫描,第一遍是找到连续1个字符的子串长度,第二遍是基于第一遍的结果然后找到所有的连续两位组合的所有子串长度,如abcd,子串为ab bc cd,d。 由于可能存在重复,e.g ababc,我会做一次合并,合并之后为 ab bc,然后第三遍扫描的时候,开始继续找连续3个字符串,然后合并。但是等我把算法写下来,最后估了一下,我发现是时间复杂度还是O(N^2)。给面试官看了一下,面试官也没有什么想聊,想着什么菜鸟啊,直接把我reject了。
(回来之后,在网上找了一下,然后发现可以一边扫描实现,然后时间复杂度可能接近 O(n) )

int findMaxKSub(String origin,int k){
    int start = 0;
    int ret = 0;
    Map<Character> charCountMap = new HashMap<Character>();
    for(int i = 0 ; i < orgin.length(); i++){
       char theC = origin.charAt(i);
       if(charCountMap.contains(theC)){
         charCountMap.put(theC,0);
       }
       charCountMap.put(theC,charCountMap.get(theC)+1);
       while(charCountMap.size() > k){
         char startC = origin.charAt(start);
         charCountMap.put(startC,charCountMap.get(startC)-);
         if(charCountMap.get(startC) == 0){
             charCountMap.remove(startC);
         }
         start++;
       }
       int len = i - start +1;
       if(len > ret){
           ret = len;
       }
    }
    return ret;
}

总结

1 在面试得时候一定要思路清晰,在没有想清楚之前不要轻易开口,即使聊到后面能完成题目,但是给面试官的影响还是会很差。
2 多刷些leetCode吧。

猜你喜欢

转载自blog.csdn.net/u010953266/article/details/81070372