微软100题面试题总结

来源:互联网 发布:海南广电网络 编辑:程序博客网 时间:2024/05/16 04:32
第一题:二叉树中序遍历,每个节点的前继是没有右节点的,每个节点的后继是没有左节点的。每个节点左节点指向前继,每个节点右节点指向后继组成双向链表。
第六题:模拟人工算法。

第9题:二叉树问题,后续遍历产生的序列特征是最后个数是根节点,然后前面的数可以分成两部分,小于根节点的和大于根节点的,从而能够分成左子树与右子树,并递归遍历左子树和右子树。
//认真复习二叉树的几个遍历。每种遍历的前继后继。

第12题:可以利用类的构造函数和析构函数来控制函数运行次数。

第17题:在选择数据结构时,可以考虑每个元素是用char,int,或者4个bit就够了。

第20题:对非法输入的检查十分重要 。

第21题:O(2^n)复杂度,太大,不过也没什么好办法。如果不是1-n求和m,那么可以改下程序,先判断十分sum>n,大于则取当前的n,如果不大于,则不取当前数,而如不是原题那样直接输出。

第29题:给个push序列,给个序列判断是否是pop序列。
关键:找到第一个pop的元素在push序列的位置,第二个pop的元素在push序列中的位置一定是第一个pop在push中的位置的左边(即两次pop中间没有push)或者右边(即两次pop中间有push)。

第30题:求1-n中出现1个个数。编程之美上有的好像

第32题:两个n个元素的集合,要交换两个集合的元素,使得两个集合的元素和相差最小
        问题:只能交换,不能删除增加,即结果保持集合元素个数都是n?
解题思路一样是从n=1开始,慢慢发现规律,不要一上来就写代码
//不是特别明白原理,为什么每次取最大的两个值,然后交叉放入不同集合中就可以达到差最小。应该算种贪心算法吧。
//编程之美2.18题用了动规解这道题目。
//贪心是很容易举出范例的,如1,5,6,7,8,9。 按照贪心的话分成1,7,9和5,6,8两组,但是和差为2。如果分成1,8,9与5,6,7的话,差为0。所以贪心不是最优的。

第37题:n个m+1的字符串,如果一个字符串的后m个字符与另一个字符串的前m个字符相同两个字符串可以相连,求最长相连字符串个数。
            n个节点的有向图求最大路径以及判断是否有环。floyd算法。
            

第38题:分散堆。y=3^x
            很大一个流里面获取m个随机数。用蓄水池算法。

第39题:二叉树中两个节点最大距离。左右遍历,递归。    //复杂度为O(nlogn),可以用动规做。O(n)。

第40题:实现min,pop,push都是O(1)的栈。利用辅助数组记录每个元素进入时所有元素的最小值的位置。
               n个数找m个连续的数包含k个元素,要m最小。子集包含问题。

第44题:二叉排序树,搜索最大值最小值的时间为O(lgn)不是O(n)。

第48题:最长递增子序列,普通的O(n^2)方法相对简单,可以使用O(nlgn)的算法,用一个数字MaxV[i]记录长度为i的子序列的最大字符,利用二份查找的方法找到新的字符a[i]对应的子序列,而不是把a[0]-a[i-1]全部找一遍。有一个特点,i<j 则有 MaxV[i]< MaxV[j],所以可以用二分。

第49题:int count[65535]; 是空间复杂度为O(1)吗?貌似是哦。所以以后看到空间复杂度是O(1)不一定就是一个int的空间。一定常量的空间都可以。

第55题:实现对赋值操作符=时,如果成员变量存在资源,可能引起异常时,需要先保存临时变量,再申请,放在万一申请失败而原有的变量又被覆盖了。

第57题:LCS,经典动规题目,类似的有字符串最长连续字串,即字串是连续的,不像LCS是可以不连续的。同样用个N*N的表格记录对应两个元素的相等情况。编程之美上面的3.3题和这个挺类似的。

第58题:对于递归程序,正向输出就是先输出在进递归,如果想反向输出则先进递归再输出。比如反向输出链表,就是先递归遍历链表,再输出。

第59题:friend在c++表示某个类可以作为当前类的friend来访问当前类的所有private成员。

63.在字符串中删除特定的字符。在一个字符串中删除另一个字符串中的所有字符。
将源字符串中的每一个出现在另一个字符串中的字符置为*,然后将*全部移到最后(或者最前面),然后去除所有最后的*。
所以题目的关键是怎么去除字符串中的所有”*“。
方法:反向遍历字符串。使用两个指针,一个表示当前字符,一个表示当前可以被替换的字符。每遍历一个字符将当前字符覆盖可替换字符。
int backRemoveStar(char * a){
    int cnt  = 0;
    int len = strlen(a);
    char * end = a + len - 1;
    char * star = a;
    char * begin = a;
    while(begin <= end){
        while(begin<=end && *begin == '*')begin++;
        if(begin<=end && star <= end&&begin !=star){
            *star = *begin;
        }
        ++begin;
        ++star;
    }

    cnt = end-star + 1;
    while(star<=end){
        *star = '*';
        star++;
    }
    return cnt;
}


第64题:寻找丑数,即只能有因子2,3,5的数。如4,6.。。而14不行,因为有7这个因子。
和求素数差不多,素数是如果一个数不能被比它小的所有素数整除,则该树为素数。
丑数是只能被2,3,5整除的数,即通过任意个2,3,5相乘得来的。
即任意个丑数乘以2,3,5都可以得到一个新的丑数。所以每个丑数可以乘以2,3,5,但是要保证最新得到的丑数是当前最小的。
用三个指针,一个表示可以乘2的丑数,一个表示可以乘三个丑数,一个表示可以乘以5的丑数。确保3个数的结果最小。如1*5>2*2,所以应该先做2*2,再坐1*5。
//这道题目很好,这种题目不能模拟,因为太消耗时间了。应该找出规律。
http://www.cnblogs.com/coser/archive/2011/03/07/1976525.html

第65题:用char数组表示大数。这种题目就是烦人,没什么好办法的。

第66题:这道题目不错,重新认识了递归的含义。二叉树的前后中序遍历中用到递归,可以以不同顺序遍历二叉树。单链表的逆向输出同样利用递归,而这道题目同样用到递归。
递归的本质就是利用了系统提供的函数调用堆栈来保存数据(即函数调用参数)。不用递归就相当于我们自己写一个栈,模拟函数调用时的压栈过程。

第71题:求X^y是可以用二分来做的。

第73题:找最长对称字符串。必须考虑对称中心是一个字符还是两个字符的情况,比如“google”,或者“ggoggle”这两个不同情况。

第77题:链表相交和环的问题。如果没有环,相交只要判断是否都是在end相遇即可。如果有环,则一个走2步一个走一步必相遇。如果有环求环的入口,则把环断开,然后变成两个链表求交点。两个链表求交点是先计算两个链表长度差为len,则长的先走len步,然后一起走就可以相遇在交点了。
删除一个节点O(1)时间,将后面一个复制过来,但是如果要删除最后个没办法只能从头找到最后个。平均O(1)时间。
最后第k个节点。也是这么求,先走k步,然后两个一起走。
当然链表还有什么随机链表拷贝啦,链表逆置,链表归并排序等等。
两个链表,有环,有交点,求交点的题目:http://blog.csdn.net/zcsylj/article/details/6800052。好复杂!
//当两个链表相交并且有环时,如果两个链表的环的入口不一致时,其实两个链表可以由两个交点。当然任意一个交点都可以。

原创粉丝点击