- 172.61 KB
- 2022-04-22 11:29:54 发布
- 1、本文档共5页,可阅读全部内容。
- 2、本文档内容版权归属内容提供方,所产生的收益全部归内容提供方所有。如果您对本文有版权争议,可选择认领,认领后既往收益都归您。
- 3、本文档由用户上传,本站不保证质量和数量令人满意,可能有诸多瑕疵,付费之前,请仔细先通过免费阅读内容等途径辨别内容交易风险。如存在严重挂羊头卖狗肉之情形,可联系本站下载客服投诉处理。
- 文档侵权举报电话:19940600175。
'本文转载自CSDN大牛的一篇博客:http://blog.csdn.net/v_july_v/article/details/6870251作者:July、阿财时间:二零一一年十月十三日。我能够看到此文,还要多谢陈同学!让我得以及时分享给大家微软面试100题全部答案个人整理的前60题的答案可参见以下三篇文章:1.微软100题第1题-20题答案http://blog.csdn.net/v_JULY_v/archive/2011/01/10/6126406.aspx[博文I]2.微软100题第21-40题答案http://blog.csdn.net/v_JULY_v/archive/2011/01/10/6126444.aspx[博文II]3.微软100题第41-60题答案http://blog.csdn.net/v_JULY_v/archive/2011/02/01/6171539.aspx[博文III]最新整理的全部100题的答案参见如下(重复的,以及一些无关紧要的题目跳过):1.把二元查找树转变成排序的双向链表题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。10/614//481216转换成双向链表4=6=8=10=12=14=16。首先我们定义的二元查找树节点的数据结构如下:structBSTreeNode{intm_nValue;//valueofnodeBSTreeNode*m_pLeft;//leftchildofnodeBSTreeNode*m_pRight;//rightchildofnode};ANSWER:Thisisatraditionalproblemthatcanbesolvedusingrecursion.Foreachnode,connectthedoublelinkedlistscreatedfromleftandrightchildnodetoformafulllist./***@paramrootTherootnodeofthetree*@returnTheheadnodeoftheconvertedlist.
*/BSTreeNode*treeToLinkedList(BSTreeNode*root){BSTreeNode*head,*tail;helper(head,tail,root);returnhead;}voidhelper(BSTreeNode*&head,BSTreeNode*&tail,BSTreeNode*root){BSTreeNode*lt,*rh;if(root==NULL){head=NULL,tail=NULL;return;}helper(head,lt,root->m_pLeft);helper(rh,tail,root->m_pRight);if(lt!=NULL){lt->m_pRight=root;root->m_pLeft=lt;}else{head=root;}if(rh!=NULL){root->m_pRight=rh;rh->m_pLeft=root;}else{tail=root;}}2.设计包含min函数的栈。定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)。ANSWER:StackisaLIFOdatastructure.Whensomeelementispoppedfromthestack,thestatuswillrecovertotheoriginalstatusasbeforethatelementwaspushed.Sowecanrecovertheminimumelement,too.structMinStackElement{intdata;intmin;};structMinStack{MinStackElement*data;intsize;
inttop;}MinStackMinStackInit(intmaxSize){MinStackstack;stack.size=maxSize;stack.data=(MinStackElement*)malloc(sizeof(MinStackElement)*maxSize);stack.top=0;returnstack;}voidMinStackFree(MinStackstack){free(stack.data);}voidMinStackPush(MinStackstack,intd){if(stack.top==stack.size)error(“outofstackspace.”);MinStackElement*p=stack.data[stack.top];p->data=d;p->min=(stack.top==0?d:stack.data[top-1]);if(p->min>d)p->min=d;top++;}intMinStackPop(MinStackstack){if(stack.top==0)error(“stackisempty!”);returnstack.data[--stack.top].data;}intMinStackMin(MinStackstack){if(stack.top==0)error(“stackisempty!”);returnstack.data[stack.top-1].min;}3.求子数组的最大和题目:输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。要求时间复杂度为O(n)。例如输入的数组为1,-2,3,10,-4,7,2,-5,和最大的子数组为3,10,-4,7,2,因此输出为该子数组的和18。ANSWER:Atraditionalgreedyapproach.Keepcurrentsum,slidefromlefttoright,whensum<0,resetsumto0.intmaxSubarray(inta[],intsize){if(size<=0)error(“errorarraysize”);intsum=0;intmax=-(1<<31);intcur=0;
while(curmax){max=sum;}elseif(sum<0){sum=0;}}returnmax;}4.在二元树中找出和为某一值的所有路径题目:输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相等的所有路径。例如输入整数22和如下二元树10/512/47则打印出两条路径:10,12和10,5,7。二元树节点的数据结构定义为:structBinaryTreeNode//anodeinthebinarytree{intm_nValue;//valueofnodeBinaryTreeNode*m_pLeft;//leftchildofnodeBinaryTreeNode*m_pRight;//rightchildofnode};ANSWER:Usebacktrackingandrecurison.Weneedastacktohelpbacktrackingthepath.structTreeNode{intdata;TreeNode*left;TreeNode*right;};voidprintPaths(TreeNode*root,intsum){intpath[MAX_HEIGHT];helper(root,sum,path,0);}voidhelper(TreeNode*root,intsum,intpath[],inttop){path[top++]=root.data;sum-=root.data;
if(root->left==NULL&&root->right==NULL){if(sum==0)printPath(path,top);}else{if(root->left!=NULL)helper(root->left,sum,path,top);if(root->right!=NULL)helper(root->right,sum,path,top);}top--;sum-=root.data;}5.查找最小的k个元素题目:输入n个整数,输出其中最小的k个。例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4。ANSWER:Thisisaverytraditionalquestion...O(nlogn):catI_FILE|sort-n|head-nKO(kn):doinsertionsortuntilkelementsareretrieved.O(n+klogn):TakeO(n)timetobottom-upbuildamin-heap.Thensift-downk-1times.SotraditionalthatIdon’twanttowritethecodes...Onlygivesthesiftupandsiftdownfunction./***@paramitheindexoftheelementinheapa[0...n-1]tobesiftedupvoidsiftup(inta[],inti,intn){while(i>0){intj=(i&1==0?i-1:i+1);intp=(i-1)>>1;if(jnext!=NULL){h1=h1->next;}while(h2->next!=NULL){h2=h2->next;}returnh1==h2;}//iftherecouldexistcycleintisJoined(Node*h1,Node*h2){Node*cylic1=testCylic(h1);Node*cylic2=testCylic(h2);if(cylic1+cylic2==0)returnisJoinedSimple(h1,h2);if(cylic1==0&&cylic2!=0||cylic1!=0&&cylic2==0)return0;Node*p=cylic1;while(1){if(p==cylic2||p->next==cylic2)return1;p=p->next->next;
cylic1=cylic1->next;if(p==cylic1)return0;}}Node*testCylic(Node*h1){Node*p1=h1,*p2=h1;while(p2!=NULL&&p2->next!=NULL){p1=p1->next;p2=p2->next->next;if(p1==p2){returnp1;}}returnNULL;}第8题此贴选一些比较怪的题,,由于其中题目本身与算法关系不大,仅考考思维。特此并作一题。1.有两个房间,一间房里有三盏灯,另一间房有控制着三盏灯的三个开关,这两个房间是分割开的,从一间里不能看到另一间的情况。现在要求受训者分别进这两房间一次,然后判断出这三盏灯分别是由哪个开关控制的。有什么办法呢?ANSWER:Skip.2.你让一些人为你工作了七天,你要用一根金条作为报酬。金条被分成七小块,每天给出一块。如果你只能将金条切割两次,你怎样分给这些工人?ANSWER:1+2+4;3.★用一种算法来颠倒一个链接表的顺序。现在在不用递归式的情况下做一遍。ANSWER:Node*reverse(Node*head){if(head==NULL)returnhead;if(head->next==NULL)returnhead;Node*ph=reverse(head->next);head->next->next=head;head->next=NULL;returnph;}Node*reverseNonrecurisve(Node*head){if(head==NULL)returnhead;Node*p=head;
Node*previous=NULL;while(p->next!=NULL){p->next=previous;previous=p;p=p->next;}p->next=previous;returnp;}★用一种算法在一个循环的链接表里插入一个节点,但不得穿越链接表。ANSWER:Idon’tunderstandwhatis“Chuanyue”.★用一种算法整理一个数组。你为什么选择这种方法?ANSWER:Whatis“Zhengli?”★用一种算法使通用字符串相匹配。ANSWER:Whatis“Tongyongzifuchuan”...astringwith“*”and“?”?Ifso,hereisthecode.intmatch(char*str,char*ptn){if(*ptn==‘ ’)return1;if(*ptn==‘*’){do{if(match(str++,ptn+1))return1;}while(*str!=‘ ’);return0;}if(*str==‘ ’)return0;if(*str==*ptn||*ptn==‘?’){returnmatch(str+1,ptn+1);}return0;}★颠倒一个字符串。优化速度。优化空间。voidreverse(char*str){reverseFixlen(str,strlen(str));}voidreverseFixlen(char*str,intn){char*p=str+n-1;while(str