现在的位置: 首页 > 综合 > 正文

微软的22道数据结构算法面试题(含…

2019年03月05日 ⁄ 综合 ⁄ 共 7909字 ⁄ 字号 评论关闭
1、反转一个链表。循环算法。   
    
    
    1  
  List   reverse(List
  l)   {
  
    2  
  if(!l)   return
  l;   
    3  
      list
  cur   =  
l.next;   
    4  
  list   pre   =
  l;   
    5  
  list   tmp;
  
    6  
  pre.next   =  
null;   
    7  
  while   (  
cur   )   {
  
    8  
      tmp
  =   cur;
  
    9  
      cur
  =   cur.next;
  
  10    
    tmp.next   =
  pre   
  11    
    pre   =
  tmp;   
  12     }
  
  13    
return   tmp;
  
  14   }
  
    
  2、反转一个链表。递归算法。
  
    
  1    
List   resverse(list   l)
  {   
  2    
if(!l   ||   !l.next)
  return   l;
  
  3    
   
  
  4    
    List   n
  =   reverse(l.next);
  
  5    
    l.next.next
  =   l;
  
  6    
    l.next=null;
  
  7     }
  
  8    
return   n;
  
  9   }
  
    
    
  3、广度优先遍历二叉树。
  
    1  
  void   BST(Tree
  t)   {
  
    2  
  Queue   q   =
  new   Queue();
  
    3  
  q.enque(t);
  
    4  
  Tree   t   =
  q.deque();    
  
    5  
  while(t)   {
  
    6  
     
System.out.println(t.value);
  
    7  
     
q.enque(t.left);   
    8  
     
q.enque(t.right);   
    9  
      t
  =   q.deque();
  
  10     }
  
  11   }
  
  ----------------------
  
    1class
  Node   {
  
    2  
  Tree   t;
  
    3  
  Node   next;
  
    4   }
  
    5class
  Queue   {
  
    6  
  Node   head;
  
    7  
  Node   tail;
  
    8  
  public   void
  enque(Tree   t){
  
    9  
      Node
  n   =   new
  Node();
  
  10    
    n.t   =
  t;   
  11    
    if(!tail){
  
  12    
     
  tail   =  
head   =   n;
  
  13    
    }   else
  {   
  14    
    tail.next  
=   n;   
  15    
    tail   =
  n;   
  16    
    }
  
  17     }
  
  18    
public   Tree   deque()
  {   
  19    
    if   (!head)
  {   
  20    
     
      return
  null;   
  21    
    }   else
  {   
  22    
    Node   n
  =   head;
  
  23    
    head   =
  head.next;
  
  24    
  return   n.t;
  
  25    
    }
  
  26}  
4、输出一个字符串所有排列。注意有重复字符。
  
    
    1char[]
  p;   
    2void  
perm(char   s[],   int
  i,   int   n){
  
    3   int
  j;   
    4  
char   temp;
  
    5  
for(j=0;j
    6  
  if(j!=0   &&
  s[j]==s[j-1]);
  
    7  
  elseif(s[j]!='@'){
  
    8  
    p[i]=s[j];
  
    9  
    s[j]='@';
  
  10    
  if(i==n-1){
  
  11    
    p[n]='\0';
  
  12    
    printf("%s",
  p);   
  13    
  }else{
  
  14    
    perm(s,i+1,n);
  
  15    
  }   
  16    
  s[j]=p[i];
  
  17     }
  
  18   }
  
  19}
  
  --------------------------
  
  1void   main()
  {   
  2    
char   s[N];
  
  3    
sort(s);   
  4    
perm(s,0,strlen(s));   
  5}
  
    
    
  5、输入一个字符串,输出长型整数。
  
    
    1  
long   atol(char   *str){
  
    2  
      char
  *p   =   str;
  
    3  
      long
  l=1;m=0;
  
    4  
      if
  (*p=='-')   {
  
    5  
     
     
  l=-1;   
    6  
     
     
  ++p;   
    7  
      }
  
    8  
     
while(isDigit(*p)){   
    9  
     
     
  m   =   m*10
  +   p;
  
  10    
     
      ++p;
  
  11    
    }
  
  12    
    if(!p)  
return   m*l;
  
  13    
    else  
return   error;
  
  14}
  
    
    
  6、判断一个链表是否有循环。
  
    
  1    
  int    
isLoop(List   l)  
  {   
  2    
     
  if   (   !
  l)     return
      -
  1   ;
  
  3    
      List
  s     =
    l.next;
  
  4    
     
    while   (s
    &&  
  s   !=   l)
      {
  
  5    
     
     
  s     =
    s.next;
  
  6    
      }
    
  7    
     
  if     (
  !   s)  
  return    
  -   1   ;
  
  8    
     
  else    
reutrn     1   ;
  
  9   }  
  
  -----------
  
    1int  
isLoop(List   l){
  
    2  
      if(!l)
  return   0;
  
    3  
      p=l.next;
  
    4  
     
wihle(p!=l&&p!=null)   {
  
    5  
     
     
  l.next=l;
  
    6  
     
     
  l=p;p=p.next;
  
    7  
      }
  
    8  
      if(p=l)
  return   1;
  
    9  
      return
  0;   
  10}
  
  实际上,在我的面试过程中,还问到了不破坏结构的其他算法。
  
 
我的答案是从链表头开始遍历,如果节点next指针指向自身,则循环存在;否则将next指针指向自身,遍历下一个节点。直至next指针为空,此时链表无循环。
  
    
    
  7、反转一个字符串。
  
    
    1  
    void  
  reverse(   char
      *
  str)     {
  
    2  
     
    char  
  tmp;   
    3  
     
    int  
  len;   
    4  
     
  len     =
    strlen(str);
  
    5  
     
      for
  (   int  
  i   =   0
  ;i   <  
len   /   2   ;
  ++   i)  
  {   
    6  
     
     
    tmp   =
  char   [i];
  
    7  
     
     
    str[i]  
  =     str[len
  -   i   -
  1   ];
  
    8  
     
     
    str[len   -
  i   -   1
  ]   =   tmp;
  
    9  
     
  }  
  
  10   }  
  
    
  8、实现strstr函数。
  
    
    1int  
strstr(char[]   str,   char[]
  par){   
    2  
      int
  i=0;   
    3  
      int
  j=0;   
    4  
     
while(str[i]   &&  
str[j]){   
    5  
     
     
  if(str[i]==par[j]){
  
    6  
     
     
     
    ++i;
  
    7  
     
     
     
    ++j;
  
    8  
     
     
  }else{
  
    9  
     
     
     
    i=i-j+1;
  
  10    
     
     
     
  j=0;   
  11    
     
      }
  
  12    
    }
  
  13    
    if(!str[j])
  return   i-strlen(par);
  
  14    
    else  
return   -1;
  
  15}
9、实现strcmp函数。   
    
  1int   strcmp(char*
  str1,   char*
  str2){
  
  2    
    while(*str1
  &&   *str2
  &&   *str1==*str2){
  
  3    
     
      ++str1;
  
  4    
     
      ++str2;
  
  5    
    }
  
  6    
    return  
*str1-*str2;   
  7}
  
    
    
  10、求一个整形中1的位数。
  
    
  1    
  int     f(
  int     x)
    {
  
  2    
     
  int     n
  =   0   ;
  
  3    
     
    while   (x)
    {
  
  4    
     
     
    ++   n;
  
  5    
     
     
  x   &=   x
  -   1   ;
  
  6    
      }
    
  7    
     
  return     n;
  
  8   }  
  
    
    
  11、汉诺塔问题。
  
    
  1void   tower(n,x,y,z){
  
  2    
    if(n==1)  
move(x,z);   
  3    
    else   {
  
  4    
     
      tower(n-1,
  x,z,y);
  
  5    
     
      move(x,z);
  
  6    
     
      tower(n-1,
  y,x,z);
  
  7    
    }
  
  8}
  
    
    
  12、三柱汉诺塔最小步数。
  
    
    1  
    int  
  f3(n)     {
  
    2  
     
    if   (f3[n])
    return  
  f3[n];
  
    3  
     
      else
     
  {   
    4  
     
     
     
  if   (n   ==
  1   )  
  {   
    5  
     
     
     
      f3[n]
  =   1   ;
  
    6  
     
     
     
     
  return    
  1   ;
  
    7  
     
     
    }  
  
    8  
     
     
    f3[n]   =
  2   *   f3(n
  -   1   )
  +   1   ;
  
    9  
     
     
      return
    f3[n];
  
  10    
      }
    
  11   }  
  
    
  四柱汉诺塔最小步数。
  
    1int  
f4(n){   
    2  
     
if(f4[n]==0){   
    3  
     
     
  if(n==1)   {
  
    4  
     
     
     
    f4[1]==1;
  
    5  
     
     
     
    return   1;
  
    6  
     
     
  }   
    7  
     
     
  min=2*f4(1)+f3(n-1);
  
    8  
     
     
  for(int   i=2;i
    9  
     
     
     
    u=2*f4(i)+f3(n-i);
  
  10    
     
     
     
  if(u
  11    
     
      }
  
  12    
     
      f4[n]=min;
  
  13    
     
      return
  min;   
  14    
    }   else
  return   f4[n];
  
  15}
  
    
    
  13、在一个链表中删除另一个链表中的元素。
  
    
    1void  
delete(List   m,   List
  n)   {
  
    2  
      if(!m
  ||   !n)  
return;   
    3  
      List
  pre   =   new
  List();
  
    4  
     
pre.next=m;   
    5  
      List
  a=m,   b=n,head=pre;
  
    6  
      while(a
  &&   b){
  
    7  
     
     
  if(a.value   <
  b.value)   {
  
    8  
     
     
     
    a=a.next;
  
    9  
     
     
     
    pre=pre.next;
  
  10    
     
      }else
  if(a.value   >
  b.value){
  
  11    
     
     
     
  b=b.next;
  
  12    
     
      }else{
  
  13    
     
     
     
  a=a.next;
  
  14    
     
     
     
  pre.next=a;
  
  15    
     
      }
  
  16    
    }
  
  17    
    m=head.next;
  
  18}
 14、一个数组,下标从0到n,元素为从0到n的整数。判断其中是否有重复元素。
  
    
    1int  
hasDuplicate(int[]   a,   int
  n){   
    2  
      for(int
  i=0;i
    3  
     
     
  while(a[i]!=i   &&
  a[i]!=-1){
  
    4  
     
     
     
    if(a[a[i]]==-1)
  return   1;
  
    5  
     
     
     
    a[i]=a[a[i]];
  
    6  
     
     
     
    a[a[i]]=-1;
  
    7  
     
     
  }   
    8  
     
     
  if(a[i]==i)   {a[i]=-1;}
  
    9  
      }
  
  10    
    return   0;
  
  11}
  
    
    
  15、判断一颗二叉树是否平衡。
  
    
  1int   isB(Tree
  t){   
  2    
    if(!t)  
return   0;
  
  3    
    int  
left=isB(t.left);   
  4    
    int  
right=isB(t.right);   
  5    
    if(   left
  >=0   &&
  right   >=0
  &&   left
  -   right  
<=   1   ||  
left   -right   >=-1)
  
  6    
     
      return
  (left
  7    
    else  
return   -1;
  
  8}
  
  9
  
    
    
  16、返回一颗二叉树的深度。
  
    
  1int   depth(Tree
  t){   
  2    
    if(!t)  
return   0;
  
  3    
    else   {
  
  4    
     
      int
  a=depth(t.right);
  
  5    
     
      int
  b=depth(t.left);
  
  6    
     
      return
  (a>b)?(a+1):(b+1);
  
  7    
    }
  
  8}
  
    
    
  17、两个链表,一升一降。合并为一个升序链表。
  
    
    1  
    List  
merge(List   a,   List
  d)     {
  
    2  
     
  List   a1   =
  reverse(d);
  
    3  
     
  List   p  
  =     q
    =  
    new  
  List();
  
    4  
     
      while
    (   a
    &&  
  a1   )  
    {
  
    5  
     
     
     
  if   (a.value
  <   a1.value)
    {
  
    6  
     
     
     
      p.next
  =   a;
  
    7  
     
     
     
      a
  =   a.next;
  
    8  
     
     
      }
      else
     
  {   
    9  
     
     
     
      p.next
  =   a1;
  
  10    
     
     
     
    a1   =
  a1.next;
  
  11    
     
     
  }  
  
  12    
     
     
  p   =  
p.next;   
  13    
      }
    
  14    
     
  if   (a)  
p.next     =  
  a;   
  15    
      elseif(a1)
  p.next   =  
a1;   
  16    
     
  return    
q.next;   
  17   }  
  
    
    
  18、将长型转换为字符串。
  
    
    1char*
  ltoa(long   l){
  
    2  
      char[N]
  str;  
  
    3  
      int
  i=1,n=1;
  
    4  
     
while(!(l/i<10)){i*=10;++n}
  
    5  
      char*
  str=(char*)malloc(n*sizeof(char));
  
    6  
      int
  j=0;   
    7  
      while(l){
  
    8  
     
     
  str[j++]=l/i;
  
    9  
     
     
  l=l%i;
  
  10    
     
      i/=10;
  
  11    
    }
  
  12    
    return  
str;   
  13}
  
19、用一个数据结构实现   
  1   if  
(x   ==   0)   y
  =   a;
  
  2   else
  y   =   b;
  
    
  1   j[]  
=   {a,b};
  
  2   y=j[x];
  
    
    
  20、在双向链表中删除指定元素。
  
    
    1void  
del(List   head,   List
  node){
  
    2  
      List
  pre=new   List();
  
    3  
      pre.next
  =   head;
  
    4  
      List
  cur   =  
head;   
    5  
      while(cur
  &&   cur!=node){
  
    6  
     
     
  cur=cur.next;
  
    7  
     
     
  pre=pre.next;
  
    8  
      }
  
    9  
      if(!cur)
  return;
  
  10    
    List   post
  =   cur.next;
  
  11    
    pre.next=cur.next;
  
  12    
    post.last=cur.last;
  
  13    
    return;
  
  14}
  
    
  21、不重复地输出升序数组中的元素。
  
    
    1  
    void  
  outputUnique(   char
  []   str,  
int     n)  
  {   
    2  
     
    if   (n
  <=   0   )
    return   ;
  
    3  
     
  elseif(n   ==
  1   )  
putchar(str[   0   ]);
  
    4  
     
      else
     
  {   
    5  
     
     
      int
    i   =
  0   ,j   =
  1   ;
  
    6  
     
     
    putchar(str[
  0   ]);
  
    7  
     
     
     
  while   (j  
<   n)     {
  
    8  
     
     
     
     
    if   (str[j]
  !==   str[i])
    {
  
    9  
     
     
     
     
     
  putchar(str[j]);
  
  10    
     
     
     
     
      i
  =   j;
  
  11    
     
     
     
    }  
  
  12    
     
     
     
      ++
  j;   
  13    
     
     
  }  
  
  14    
      }
    
  15   }  
  
    
    
  22、面试过程中我还遇到了下面几题:
  
    
 
1、如何删除链表的倒数第m的元素?我的方法是先用pre指针从链表头开始步进m,新建pst节点next指针指向头节点,cur指针指向头节点,然后pre,cur,post三个指针一起步进,当pre指向链表结尾的时候cur指向倒数第m个元素,最后利用pst指针删除cur指向元素。
  
    
 
2、如何判断一个字符串是对称的?如a,aa,aba。设置头尾指针同时向中间比较靠齐直至相遇。
  
    
 
3、如何利用2函数找出一个字符串中的所有对称子串?以子串头指针和尾指针为循环变量设置两个嵌套的循环以找出所有子串,对每个子串应用2函数。
 
 
该系列题目由http://www.cnblogs.com/wqguan/archive/2006/06/20/430347.html
  
  的作者GwQ收集整理,我只是转贴 

【上篇】
【下篇】

抱歉!评论已关闭.