1、微软 等数据 结构 + + + + 算法 面试 1 0 0 1 0 0 1 0 0 1 0 0 题全 部答案 集锦 作者: J u l y 、阿财。 时间:二零一一年十月十三日。 引言 无私分享造就开源的辉煌。 今是二零一一年十月十三日,明日1 4 日即是本人刚好开博一周年。在一周年之际,特此分享出微软面试 全部 1 0 0 题答案的完整版,以作为对本博客所有读者的回馈。 一年之前的1 0 月1 4 日,一个名叫 J u l y 的人在一个叫 c s d n 的论坛上开帖分享微软等公司数据结构+ 算法 面试 1 0 0 题,自此,与上千网友一起做,一起思考,一起解答这些面试题目,最终成就了一个
2、名为:结构之法 算法之道 的 编程面试与算法研究 并重的博客,如今,此博客影响力逐步渗透到海外,及至到整个互联网。 在此之前,由于本人笨拙,这微软面试1 0 0 题的答案只整理到了前6 0 题(第1 - 6 0 题答案可到本人资源下 载处下载:h t t p : / / v _ j u l y _ v . d o w n l o a d . c s d n . n e t / h t t p : / / v _ j u l y _ v . d o w n l o a d . c s d n . n e t / h t t p : / / v _ j u l y _ v . d o w n l
3、o a d . c s d n . n e t / h t t p : / / v _ j u l y _ v . d o w n l o a d . c s d n . n e t / ),故此,常有朋友留言或来信询问后面4 0 题的答案。只是 因个人认为:一、答案只是作为一个参考,不可太过依赖;二、常常因一些事情耽搁(如在整理最新的今年 九月、十月份的面试题:九月腾讯,创新工场,淘宝等公司最新面试十三题 、十月百度,阿里巴巴,迅雷搜狗 最新面试十一题);三、个人正在针对那 1 0 0 题一题一题的写文章,多种思路,不断优化,即成程序员编 程 艺术系列。自此,后面4 0 题的答案迟迟未得整理
4、。且个人已经整理的前6 0 题的答案,在我看来,是有诸多问 题与弊端的,甚至很多答案都是错误的。 互联网总是能给人带来惊喜。前几日,一位现居美国加州的名叫阿财的朋友发来一封邮件,并把他自己 做的全部 1 0 0 题的答案一并发予给我,自此,便似遇见了知己。十分感谢。 任何东西只有分享出来才更显其价值。本只需贴出后面4 0 题的答案,因为前6 0 题的答案本人早已整理上 传至网上,但多一种思路多一种参考亦未尝不可。特此,把阿财的答案再稍加整理番,然后把全部1 0 0 题的答 案现今都贴出来。若有任何问题,欢迎不吝指正。谢谢。 上千上万的人都关注过此1 0 0 题,且大都都各自贡献了自己的思路,或
5、回复于微软1 0 0 1 0 0 1 0 0 1 0 0 题维护地址上,或 回复于本博客内,人数众多,无法一一标明,特此向他们诸位表示敬意和感谢。谢谢大家,诸君的努力足以影 响整个互联网,咱们已经迎来一个分享互利的新时代。 微软 面试 1 0 0 1 0 0 1 0 0 1 0 0 题全 部答案 最新整理的全部 1 0 0 题的答案参见如下(重复的,以及一些无关紧要的题目跳过。且因尊重阿财,未作过 多修改。因此,有些答案是有问题的 ,重点还可关注本人的程序 员编程 艺术系 列 ,亦可参考个人之前 整理的前 6 0 题的答案:第1 题- 2 0 题答案: h t t p : / / b l o
6、g . c s d n . n e t / v _ J U L Y _ v / a r c h i v e / 2 0 1 1 / 0 1 / 1 0 / 6 1 2 6 4 0 6 . a s p x , 第 2 1 - 4 0 题答案:h t t p : / / b l o g . c s d n . n e t / v _ J U L Y _ v / a r c h i v e / 2 0 1 1 / 0 1 / 1 0 / 6 1 2 6 4 4 4 . a s p x ,第4 1 - 6 0 题答案: h t t p : / / b l o g . c s d n . n e t /
7、 v _ J U L Y _ v / a r c h i v e / 2 0 1 1 / 0 2 / 0 1 / 6 1 7 1 5 3 9 . a s p x ): 1 . 把二元查找树转变成排序的双向链表 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 要求不能创建任何新的结点,只调整指针的指向。 1 0 / 6 1 4 / / 4 8 1 2 1 6 转换成双向链表 4 = 6 = 8 = 1 0 = 1 2 = 1 4 = 1 6 。首先我们定义的二元查找树节点的数据结构如下: s t r u c t B S T r e e N o d e i n t m _ n
8、 V a l u e ; / / v a l u e o f n o d e B S T r e e N o d e * m _ p L e f t ; / / l e f t c h i l d o f n o d e B S T r e e N o d e * m _ p R i g h t ; / / r i g h t c h i l d o f n o d e ; A N S W E R : T h i s i s a t r a d i t i o n a l p r o b l e m t h a t c a n b e s o l v e d u s i n g r e c u
9、 r s i o n . F o r e a c h n o d e , c o n n e c t t h e d o u b l e l i n k e d l i s t s c r e a t e d f r o m l e f t a n d r i g h t c h i l d n o d e t o f o r m a f u l l l i s t . / * * * p a r a m r o o t T h e r o o t n o d e o f t h e t r e e * r e t u r n T h e h e a d n o d e o f t h e c
10、 o n v e r t e d l i s t . * / B S T r e e N o d e * t r e e T o L i n k e d L i s t ( B S T r e e N o d e * r o o t ) B S T r e e N o d e * h e a d , * t a i l ; h e l p e r ( h e a d , t a i l , r o o t ) ; r e t u r n h e a d ; v o i d h e l p e r ( B S T r e e N o d e * i f ( r o o t = = N U L L
11、 ) h e a d = N U L L , t a i l = N U L L ; r e t u r n ; h e l p e r ( h e a d , l t , r o o t - m _ p L e f t ) ; h e l p e r ( r h , t a i l , r o o t - m _ p R i g h t ) ; i f ( l t ! = N U L L ) l t - m _ p R i g h t = r o o t ; r o o t - m _ p L e f t = l t ; e l s e h e a d = r o o t ; i f ( r
12、 h ! = N U L L ) r o o t - m _ p R i g h t = r h ; r h - m _ p L e f t = r o o t ; e l s e t a i l = r o o t ; 2 . 设计包含 m i n 函数的栈。 定义栈的数据结构,要求添加一个 m i n 函数,能够得到栈的最小元素。 要求函数 m i n 、 p u s h 以及 p o p 的时间复杂度都是 O ( 1 ) 。 A N S W E R : S t a c k i s a L I F O d a t a s t r u c t u r e . W h e n s o m e
13、e l e m e n t i s p o p p e d f r o m t h e s t a c k , t h e s t a t u s w i l l r e c o v e r t o t h e o r i g i n a l s t a t u s a s b e f o r e t h a t e l e m e n t w a s p u s h e d . S o w e c a n r e c o v e r t h e m i n i m u m e l e m e n t , t o o . s t r u c t M i n S t a c k E l e m
14、e n t i n t d a t a ; i n t m i n ; ; s t r u c t M i n S t a c k M i n S t a c k E l e m e n t * d a t a ; i n t s i z e ; i n t t o p ; M i n S t a c k M i n S t a c k I n i t ( i n t m a x S i z e ) M i n S t a c k s t a c k ; s t a c k . s i z e = m a x S i z e ;s t a c k . d a t a = ( M i n S t
15、 a c k E l e m e n t * ) m a l l o c ( s i z e o f ( M i n S t a c k E l e m e n t ) * m a x S i z e ) ; s t a c k . t o p = 0 ; r e t u r n s t a c k ; v o i d M i n S t a c k F r e e ( M i n S t a c k s t a c k ) f r e e ( s t a c k . d a t a ) ; v o i d M i n S t a c k P u s h ( M i n S t a c k s
16、 t a c k , i n t d ) i f ( s t a c k . t o p = = s t a c k . s i z e ) e r r o r ( “ o u t o f s t a c k s p a c e . ” ) ; M i n S t a c k E l e m e n t * p = s t a c k . d a t a s t a c k . t o p ; p - d a t a = d ; p - m i n = ( s t a c k . t o p = = 0 ? d : s t a c k . d a t a t o p - 1 ) ; i f (
17、 p - m i n d ) p - m i n = d ; t o p + + ; i n t M i n S t a c k P o p ( M i n S t a c k s t a c k ) i f ( s t a c k . t o p = = 0 ) e r r o r ( “ s t a c k i s e m p t y ! ” ) ; r e t u r n s t a c k . d a t a - - s t a c k . t o p . d a t a ; i n t M i n S t a c k M i n ( M i n S t a c k s t a c k
18、 ) i f ( s t a c k . t o p = = 0 ) e r r o r ( “ s t a c k i s e m p t y ! ” ) ; r e t u r n s t a c k . d a t a s t a c k . t o p - 1 . m i n ; 3 . 求子数组的最大和 题目: 输入一个整形数组,数组里有正数也有负数。 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。 求所有子数组的和的最大值。要求时间复杂度为 O ( n ) 。 例如输入的数组为1 , - 2 , 3 , 1 0 , - 4 , 7 , 2 , - 5 ,和最大的子
19、数组为3 , 1 0 , - 4 , 7 , 2 , 因此输出为该子数组的和1 8 。 A N S W E R : A t r a d i t i o n a l g r e e d y a p p r o a c h . K e e p c u r r e n t s u m , s l i d e f r o m l e f t t o r i g h t , w h e n s u m m a x ) m a x = s u m ; e l s e i f ( s u m 0 ) s u m = 0 ; r e t u r n m a x ; 4 . 在二元树中找出和为某一值的所有路径
20、题目:输入一个整数和一棵二元树。 从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。 打印出和与输入整数相等的所有路径。 例如输入整数2 2 和如下二元树 1 0 / 5 1 2 / 4 7则打印出两条路径:1 0 , 1 2 和1 0 , 5 , 7 。 二元树节点的数据结构定义为: s t r u c t B i n a r y T r e e N o d e / / a n o d e i n t h e b i n a r y t r e e i n t m _ n V a l u e ; / / v a l u e o f n o d e B i n a r y T
21、r e e N o d e * m _ p L e f t ; / / l e f t c h i l d o f n o d e B i n a r y T r e e N o d e * m _ p R i g h t ; / / r i g h t c h i l d o f n o d e ; A N S W E R : U s e b a c k t r a c k i n g a n d r e c u r i s o n . W e n e e d a s t a c k t o h e l p b a c k t r a c k i n g t h e p a t h . s
22、t r u c t T r e e N o d e i n t d a t a ; T r e e N o d e * l e f t ; T r e e N o d e * r i g h t ; ; v o i d p r i n t P a t h s ( T r e e N o d e * r o o t , i n t s u m ) i n t p a t h M A X _ H E I G H T ; h e l p e r ( r o o t , s u m , p a t h , 0 ) ; v o i d h e l p e r ( T r e e N o d e * r
23、o o t , i n t s u m , i n t p a t h , i n t t o p ) p a t h t o p + + = r o o t . d a t a ; s u m - = r o o t . d a t a ; i f ( r o o t - l e f t = = N U L L e l s e i f ( r o o t - l e f t ! = N U L L ) h e l p e r ( r o o t - l e f t , s u m , p a t h , t o p ) ; i f ( r o o t - r i g h t ! = N U
24、L L ) h e l p e r ( r o o t - r i g h t , s u m , p a t h , t o p ) ; t o p - - ; s u m - = r o o t . d a t a ; 5 . 查找最小的 k 个元素 题目:输入 n 个整数,输出其中最小的 k 个。 例如输入 1 ,2 ,3 ,4 ,5 ,6 ,7 和8 这8 个数字,则最小的4 个数字为1 ,2 ,3 和4 。 A N S W E R : T h i s i s a v e r y t r a d i t i o n a l q u e s t i o n . . . O ( n l o
25、 g n ) : c a t I _ F I L E | s o r t - n | h e a d - n K O ( k n ) : d o i n s e r t i o n s o r t u n t i l k e l e m e n t s a r e r e t r i e v e d . O ( n + k l o g n ) : T a k e O ( n ) t i m e t o b o t t o m - u p b u i l d a m i n - h e a p . T h e n s i f t - d o w n k - 1 t i m e s . S o t
26、 r a d i t i o n a l t h a t I d o n t w a n t t o w r i t e t h e c o d e s . . . O n l y g i v e s t h e s i f t u p a n d s i f t d o w n f u n c t i o n . / * * * p a r a m i t h e i n d e x o f t h e e l e m e n t i n h e a p a 0 . . . n - 1 t o b e s i f t e d u p v o i d s i f t u p ( i n t a
27、 , i n t i , i n t n ) w h i l e ( i 0 ) i n t j = ( i i n t p = ( i - 1 ) 1 ; i f ( j n i f ( a i a p ) s w a p ( a , i , p ) ; i = p ; v o i d s i f t d o w n ( i n t a , i n t i , i n t n ) w h i l e ( 2 * i + 1 n ) i n t l = 2 * i + 1 ; i f ( l + 1 n i f ( a l a i ) s w a p ( a , i , l ) ; i = l
28、 ; 第 6 题 腾讯面试题: 给你 1 0 分钟时间,根据上排给出十个数,在其下排填出对应的十个数 要求下排每个数都是先前上排那十个数在下排出现的次数。 上排的十个数如下: 【 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 次. . . . 以此类推 . . A N S W E R : I d o n
29、 t l i k e b r a i n t e a s e r s . W i l l s k i p m o s t o f t h e m . . . 第 7 题 微软亚院之编程判断俩个链表是否相交 给出俩个单向链表的头指针,比如 h 1 ,h 2 ,判断这俩个链表是否相交。 为了简化问题,我们假设俩个链表均不带环。 问题扩展: 1 . 如果链表可能有环列? 2 . 如果需要求出俩个链表相交的第一个节点列? A N S W E R : s t r u c t N o d e i n t d a t a ; i n t N o d e * n e x t ; ; / / i f t h e
30、 r e i s n o c y c l e . i n t i s J o i n e d S i m p l e ( N o d e * h 1 , N o d e * h 2 ) w h i l e ( h 1 - n e x t ! = N U L L ) h 1 = h 1 - n e x t ; w h i l e ( h 2 - n e x t ! = N U L L ) h 2 = h 2 - n e x t ; r e t u r n h 1 = = h 2 ; / / i f t h e r e c o u l d e x i s t c y c l e i n t i s
31、 J o i n e d ( N o d e * h 1 , N o d e * h 2 ) N o d e * c y l i c 1 = t e s t C y l i c ( h 1 ) ; N o d e * c y l i c 2 = t e s t C y l i c ( h 2 ) ; i f ( c y l i c 1 + c y l i c 2 = = 0 ) r e t u r n i s J o i n e d S i m p l e ( h 1 , h 2 ) ; i f ( c y l i c 1 = = 0 N o d e * p = c y l i c 1 ; w
32、 h i l e ( 1 ) i f ( p = = c y l i c 2 | | p - n e x t = = c y l i c 2 ) r e t u r n 1 ; p = p - n e x t - n e x t ; c y l i c 1 = c y l i c 1 - n e x t ; i f ( p = = c y l i c 1 ) r e t u r n 0 ; N o d e * t e s t C y l i c ( N o d e * h 1 ) N o d e * p 1 = h 1 , * p 2 = h 1 ; w h i l e ( p 2 ! = N
33、 U L L p 2 = p 2 - n e x t - n e x t ;i f ( p 1 = = p 2 ) r e t u r n p 1 ; r e t u r n N U L L ; 第 8 题 此贴选一些比较怪的题,由于其中题目本身与算法关系不大,仅考考思维。特此并作一题。 1 . 有两个房间,一间房里有三盏灯,另一间房有控制着三盏灯的三个开关, 这两个房间是分割开的,从一间里不能看到另一间的情况。 现在要求受训者分别进这两房间一次,然后判断出这三盏灯分别是由哪个开关控制的。 有什么办法呢? A N S W E R : S k i p . 2 . 你让一些人为你工作了七天,你要用
34、一根金条作为报酬。金条被分成七小块,每天给出一 块。 如果你只能将金条切割两次,你怎样分给这些工人? A N S W E R : 1 + 2 + 4 ; 3 . 用一种算法来颠倒一个链接表的顺序。现在在不用递归式的情况下做一遍。 A N S W E R : N o d e * r e v e r s e ( N o d e * h e a d ) i f ( h e a d = = N U L L ) r e t u r n h e a d ; i f ( h e a d - n e x t = = N U L L ) r e t u r n h e a d ; N o d e * p h =
35、 r e v e r s e ( h e a d - n e x t ) ; h e a d - n e x t - n e x t = h e a d ; h e a d - n e x t = N U L L ; r e t u r n p h ; N o d e * r e v e r s e N o n r e c u r i s v e ( N o d e * h e a d ) i f ( h e a d = = N U L L ) r e t u r n h e a d ; N o d e * p = h e a d ; N o d e * p r e v i o u s = N
36、 U L L ; w h i l e ( p - n e x t ! = N U L L ) p - n e x t = p r e v i o u s ; p r e v i o u s = p ; p = p - n e x t ; p - n e x t = p r e v i o u s ; r e t u r n p ; 用一种算法在一个循环的链接表里插入一个节点,但不得穿越链接表。 A N S W E R : I d o n t u n d e r s t a n d w h a t i s “ C h u a n y u e ” . 用一种算法整理一个数组。你为什么选择这种方法
37、? A N S W E R : W h a t i s “ Z h e n g l i ? ” 用一种算法使通用字符串相匹配。 A N S W E R : W h a t i s “ T o n g y o n g z i f u c h u a n ” . . . a s t r i n g w i t h “ * ” a n d “ ? ” ? I f s o , h e r e i s t h e c o d e . i n t m a t c h ( c h a r * s t r , c h a r * p t n ) i f ( * p t n = = 0 ) r e t u r
38、n 1 ; i f ( * p t n = = * ) d o i f ( m a t c h ( s t r + + , p t n + 1 ) ) r e t u r n 1 ; w h i l e ( * s t r ! = 0 ) ; r e t u r n 0 ; i f ( * s t r = = 0 ) r e t u r n 0 ;i f ( * s t r = = * p t n | | * p t n = = ? ) r e t u r n m a t c h ( s t r + 1 , p t n + 1 ) ; r e t u r n 0 ; 颠倒一个字符串。优化速度。
39、优化空间。 v o i d r e v e r s e ( c h a r * s t r ) r e v e r s e F i x l e n ( s t r , s t r l e n ( s t r ) ) ; v o i d r e v e r s e F i x l e n ( c h a r * s t r , i n t n ) c h a r * p = s t r + n - 1 ; w h i l e ( s t r = 0 i f ( k 0 ) r e t u r n j + 1 ; i f ( i + 1 n ) i + = a u x s t r i + 1 ;
40、e l s e r e t u r n - 1 ; H o w e v e r , t h i s a l g o r i t h m , a s w e l l a s B M , K M P a l g o r i t h m s u s e O ( | s u b | ) s p a c e . I f t h i s i s n o t a c c e p t a b l e , R a b i n - c a r p a l g o r i t h m c a n d o i t . U s i n g h a s h i n g t o f a s t f i l t e r o
41、u t m o s t f a l s e m a t c h i n g s . # d e f i n e H B A S E 1 2 7 i n t r c _ s t r s t r ( c h a r * s t r , c h a r * s u b ) i n t d e s t = 0 ;c h a r * p = s u b ; i n t l e n = 0 ; i n t T O _ R E D U C E = 1 ; w h i l e ( * p ! = 0 ) d e s t = H B A S E * d e s t + ( i n t ) ( * p ) ; T
42、 O _ R E D U C E * = H B A S E ; l e n + + ; i n t h a s h = 0 ; p = s t r ; i n t i = 0 ; w h i l e ( * p ! = 0 ) i f ( i + + = l e n p + + ; r e t u r n - 1 ; 比较两个字符串,用 O ( n ) 时间和恒量空间。 A N S W E R : W h a t i s “ c o m p a r i n g t w o s t r i n g s ” ? J u s t n o r m a l s t r i n g c o m p a
43、r i s o n ? T h e n a t u r a l w a y u s e O ( n ) t i m e a n d O ( 1 ) s p a c e . i n t s t r c m p ( c h a r * p 1 , c h a r * p 2 ) w h i l e ( * p 1 ! = 0 i f ( * p 1 = = 0 i f ( * p 1 = = 0 ) r e t u r n - 1 ; i f ( * p 2 = = 0 ) r e t u r n 1 ; r e t u r n ( * p 1 - * p 2 ) ; / / i t c a n
44、b e n e g o t i a t e d w h e t h e r t h e a b o v e 3 i f s a r e n e c e s s a r y , I d o n t l i k e t o o m i t t h e m . 假设你有一个用 1 0 0 1 个整数组成的数组,这些整数是任意排列的,但是你知道所有的整数都在1 到 1 0 0 0 ( 包括1 0 0 0 ) 之间。此外,除一个数字出现两次外,其他所有数字只出现一次。假设你只能对这个数组做 一次处理,用一种算法找出重复的那个数字。如果你在运算中使用了辅助的存储方式,那么你能找到不用这种 方式的算法吗?
45、A N S W E R : S u m u p a l l t h e n u m b e r s , t h e n s u b t r a c t t h e s u m f r o m 1 0 0 1 * 1 0 0 2 / 2 . A n o t h e r w a y , u s e A X O R A X O R B = B : i n t f i n d X ( i n t a ) i n t k = a 0 ; f o r ( i n t i = 1 ; i = 1 0 0 0 ; i + + ) k = a i i ; r e t u r n k ; 不用乘法或加法增加 8
46、倍。现在用同样的方法增加7 倍。 A N S W E R : n 3 ; ( n 3 ) - n ; 第 9 题 判断整数序列是不是二元查找树的后序遍历结果 题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。 如果是返回 t r u e ,否则返回 f a l s e 。 例如输入 5 、7 、6 、9 、1 1 、1 0 、8 ,由于这一整数序列是如下树的后序遍历结果: 8 / 6 1 0 / / 5 7 9 1 1因此返回 t r u e 。 如果输入 7 、4 、6 、5 ,没有哪棵树的后序遍历的结果是这个序列,因此返回 f a l s e 。 A N S W E R
47、 : T h i s i s a n i n t e r e s t i n g o n e . T h e r e i s a t r a d i t i o n a l q u e s t i o n t h a t r e q u i r e s t h e b i n a r y t r e e t o b e r e - c o n s t r u c t e d f r o m m i d / p o s t / p r e o r d e r r e s u l t s . T h i s s e e m s s i m i l a r . F o r t h e p r o b
48、 l e m s r e l a t e d t o ( b i n a r y ) t r e e s , r e c u r s i o n i s t h e f i r s t c h o i c e . I n t h i s p r o b l e m , w e k n o w i n p o s t - o r d e r r e s u l t s , t h e l a s t n u m b e r s h o u l d b e t h e r o o t . S o w e h a v e k n o w n t h e r o o t o f t h e B S T i s 8 i n t h e e x a m p l e . S o w e c a n s p l i t t h e a r r a y b y t h e r o o t . i n t i s P o s t o r d e r R e s u l t ( i n t a , i n t n ) r e t u r n h e l p e r ( a , 0 , n - 1 ) ;