微软等数据结构+算法面试100题全部答案集锦Word文档下载推荐.docx
《微软等数据结构+算法面试100题全部答案集锦Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《微软等数据结构+算法面试100题全部答案集锦Word文档下载推荐.docx(58页珍藏版)》请在冰豆网上搜索。
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!
m_pRight=rh;
rh->
m_pLeft=root;
}else{
tail=root;
2.设计包含min函数的栈。
定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。
要求函数min、push以及pop的时间复杂度都是O
(1)。
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;
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){
returnstack.data[stack.top-1].min;
3.求子数组的最大和
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。
要求时间复杂度为O(n)。
例如输入的数组为1,-2,3,10,-4,7,2,-5,和最大的子数组为3,10,-4,7,2,
因此输出为该子数组的和18。
Atraditionalgreedyapproach.
Keepcurrentsum,slidefromlefttoright,whensum<
0,resetsumto0.
intmaxSubarray(inta[],intsize){
if(size<
=0)error(“errorarraysize”);
intsum=0;
intmax=-(1<
<
31);
intcur=0;
while(cur<
size){
sum+=a[cur++];
if(sum>
max){
max=sum;
}elseif(sum<
0){
sum=0;
returnmax;
4.在二元树中找出和为某一值的所有路径
输入一个整数和一棵二元树。
从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。
打印出和与输入整数相等的所有路径。
例如输入整数22和如下二元树
512
47
则打印出两条路径:
10,12和10,5,7。
二元树节点的数据结构定义为:
structBinaryTreeNode//anodeinthebinarytree
BinaryTreeNode*m_pLeft;
BinaryTreeNode*m_pRight;
Usebacktrackingandrecurison.Weneedastacktohelpbacktrackingthepath.
structTreeNode{
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&
&
right==NULL){
if(sum==0)printPath(path,top);
left!
=NULL)helper(root->
left,sum,path,top);
right!
=NULL)helper(root->
right,sum,path,top);
top--;
5.查找最小的k个元素
输入n个整数,输出其中最小的k个。
例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4。
Thisisaverytraditionalquestion...
O(nlogn):
catI_FILE|sort-n|head-nK
O(kn):
doinsertionsortuntilkelementsareretrieved.
O(n+klogn):
TakeO(n)timetobottom-upbuildamin-heap.Thensift-downk-1times.
SotraditionalthatIdon’twanttowritethecodes...
Onlygivesthesiftupandsiftdownfunction.
*@paramitheindexoftheelementinheapa[0...n-1]tobesiftedup
voidsiftup(inta[],inti,intn){
while(i>
0){
intj=(i&
1==0?
i-1:
i+1);
intp=(i-1)>
>
1;
if(j<
n&
a[j]<
a[i])i=j;
if(a[i]<
a[p])swap(a,i,p);
i=p;
}
voidsiftdown(inta[],inti,intn){
while(2*i+1<
n){
intl=2*i+1;
if(l+1<
a[l+1]<
a[l])l++;
if(a[l]<
a[i])swap(a,i,l);
i=l;
第6题
腾讯面试题:
给你10分钟时间,根据上排给出十个数,在其下排填出对应的十个数
要求下排每个数都是先前上排那十个数在下排出现的次数。
上排的十个数如下:
【0,1,2,3,4,5,6,7,8,9】
举一个例子,
数值:
0,1,2,3,4,5,6,7,8,9
分配:
6,2,1,0,0,0,1,0,0,0
0在下排出现了6次,1在下排出现了2次,
2在下排出现了1次,3在下排出现了0次....
以此类推..
Idon’tlikebrainteasers.Willskipmostofthem...
第7题
微软亚院之编程判断俩个链表是否相交
给出俩个单向链表的头指针,比如h1,h2,判断这俩个链表是否相交。
为了简化问题,我们假设俩个链表均不带环。
问题扩展:
1.如果链表可能有环列?
2.如果需要求出俩个链表相交的第一个节点列?
structNode{
intNode*next;
//ifthereisnocycle.
intisJoinedSimple(Node*h1,Node*h2){
while(h1->
next!
=NULL){
h1=h1->
next;
while(h2->
h2=h2->
next;
returnh1==h2;
//iftherecouldexistcycle
intisJoined(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->
cylic1=cylic1->
if(p==cylic1)return0;
Node*testCylic(Node*h1){
Node*p1=h1,*p2=h1;
while(p2!
=NULL&
p2->
next!
p1=p1->
p2=p2->
if(p1==p2){
returnp1;
returnNULL;
第8题
此贴选一些比较怪的题,,由于其中题目本身与算法关系不大,仅考考思维。
特此并作一题。
1.有两个房间,一间房里有三盏灯,另一间房有控制着三盏灯的三个开关,
这两个房间是分割开的,从一间里不能看到另一间的情况。
现在要求受训者分别进这两房间一次,然后判断出这三盏灯分别是由哪个开关控制的。
有什么办法呢?
Skip.
2.你让一些人为你工作了七天,你要用一根金条作为报酬。
金条被分成七小块,每天给出一
块。
如果你只能将金条切割两次,你怎样分给这些工人?
1+2+4;
3.★用一种算法来颠倒一个链接表的顺序。
现在在不用递归式的情况下做一遍。
Node*reverse(Node*head){
if(head==NULL)returnhead;
if(head->
next==NULL)returnhead;
Node*ph=reverse(head->
next);
head->
next=head;
next=NULL;
returnph;
Node*reverseNonrecurisve(Node*head){
Node*p=head;
Node*previous=NULL;
while(p->
next=previous;
previous=p;
p=p->
returnp;
★用一种算法在一个循环的链接表里插入一个节点,但不得穿越链接表。
Idon’tunderstandwhatis“Chuanyue”.
★用一种算法整理一个数组。
你为什么选择这种方法?
Whatis“Zhengli?
”
★用一种算法使通用字符串相匹配。
Whatis“Tongyongzifuchuan”...astringwith“*”and“?
”?
Ifso,hereisthecode.
intmatch(char*str,char*ptn){
if(*ptn==‘\0’)return1;
if(*ptn==‘*’){
do{
if(match(str++,ptn+1))return1;
}while(*str!
=‘\0’);
return0;
if(*str==‘\0’)return0;
if(*str==*ptn||*ptn==‘?
’){
returnmatch(str+1,ptn+1);
★颠倒一个字符串。
优化速度。
优化空间。
voidreverse(char*str){
reverseFixlen(str,strlen(str));
voidreverseFixlen(char*str,intn){
char*p=str+n-1;
while(str<
p){
charc=*str;
*str=*p;
*p=c;
★颠倒一个句子中的词的顺序,比如将“我叫克丽丝”转换为“克丽丝叫我”,
实现速度最快,移动最少。
Reversethewholestring,thenreverseeachword.UsingthereverseFixlen()above.
voidreverseWordsInSentence(char*sen){
intlen=strlen(sen);
reverseFixlen(sen,len);
char*p=str;
while(*p!
=’\0’){
while(*p==‘‘&
*p!
=’\0’)p++;
str=p;
while(p!
=‘‘&
reverseFixlen(str,p-str);
★找到一个子字符串。
KMP?
BM?
Sunday?
UsingBMorsunday,ifit’sASCIIstring,thenit’seasytofastaccesstheauxiliaryarray.Otherwiseanhashmaporbstmaybeneeded.Letsassumeit’sanASCIIstring.
intbm_strstr(char*str,char*sub){
intlen=strlen(sub);
inti;
intaux[256];
memset(aux,sizeof(int),256,len+1);
for(i=0;
i<
len;
i++){
aux[sub[i]]=len-i;
intn=strlen(str);
i=len-1;
while(i<
n){
intj=i,k=len-1;
while(k>
str[j--]==sub[k--])
;
if(k<
0)returnj+1;
if(i+1<
n)
i+=aux[str[i+1]];
else
return-1;
However,thisalgorithm,aswellasBM,KMPalgorithmsuseO(|sub|)space.Ifthisisnotacceptable,Rabin-carpalgorithmcandoit.Usinghashingtofastfilteroutmostfalsematchings.
#defineHBASE127
intrc_strstr(char*str,char*sub){
intdest=0;
char*p=sub;
intlen=0;
intTO_REDUCE=1;
dest=HBASE*dest+(int)(*p);
TO_REDUCE*=HBASE;
len++;
inthash=0;
p=str;
inti=0;
while(*p!
=‘\0’){
if(i++<
len)hash=HBASE*dest+(int)(*p);
elsehash=(hash-(TO_REDUCE*(int)(*(p-len))))*HBASE+(int)(*p);
if(hash==dest&
i>
=len&
strncmp(sub,p-len+1,len)==0)returni-len;
p++;
★比较两个字符串,用O(n)时间和恒量空间。
Whatis“comparingtwostrings”?
Justnormalstringcomparison?
ThenaturalwayuseO(n)timeandO
(1)space.
intstrcmp(char*p1,char*p2){
while(*p1!
=‘\0’&
*p2!
*p1==*p2){
p1++,p2++;
if(*p1==‘\0’&
*p2==‘\0’)return0;
if(*p1==‘\0’)return-1;
if(*p2==‘\0’)return1;
return(*