pre
算上15年,本科那次,这已经是第二次微软面试了,可惜两次都没有过,之前是面实习,走到了三面,然后讨论算法的时候没有被认可,被刷了。这次感觉是准备不充分,一面的时候表现的思路太混乱,被reject,二面面试官也没有给我好脸色,然后算法部分没有给出最优算法,果断被刷掉了。
基本过程
笔试
没有太大的难度,编程基本功扎实就能过,很水,不多聊。
一面
一面面试官针对我最近的一次的实习内容做了提问,可能因为很多业务相关,并且面试官对于我那份实习相关的知识并不精通,所以实习背景部分聊的还OK,接下来就是两条笔试题。
第一条是评断平面上一堆点是否在两条直线上,我在思考了一阵之后,还是决定,先选取前三个点,判断是否共线,如果共线,尝试在该直线之外找到一条新的直线,在检查剩下的所有点是否在这两条直线上,如果三点共线,那么我可以确定三条直线,然后假设任何一条是目标直线,然后根据另外一个点尝试构建一条新的直线,然后检查平面上的其他的点。算法复杂度大概是 O(n).。在回答的过程中,我思路有点混乱,在构建直线的时候,忘记考虑x=xi的问题,然后被指了出来,最终修修补补把整个程序怼了出来,看起来面试官还不错,没有因此就直接把我reject了。
第二条是已知一个人的日程表,日程表中有很多任务,每个任务有一个开始和一个结束时间,任务之间可能重叠,这边的时间是一个虚构的概念,时间的值可以任取,范围不做限制。我的第一想法是构建线段树,但是应为时间范围不受控,我放弃了(当然这是一个错误决策,之后会说)。然后我提出了根据任务的开始时间进行排序,然后对于存在重叠时间的任务做合并,也就是构建繁忙时间段,然后根据时间去查询空闲时间,基本的时间是排序的时间复杂度是O(N logN),然后做合并的过程是O(N),最后查询的过程也是O(N)。 当然,我觉得面试官还是不喜欢这个算法, 然后他最后也暗示我了有更有的算法,然后我想起来了离散的线段树,首先将所有的开始时间和结束时间收集起来,然后做排序,根据排序做与index 的映射,然后构建离散线段树,最后构建的过程是Nlog N , 然后查询的过