没有合适的资源?快使用搜索试试~ 我知道了~
首页【July整理】微软等数据结构+算法面试100题[附完整答案]
资源详情
资源评论
资源推荐

微软等数据结构 +
+
+
+ 算法面试 100
100
100
100 题全部答案集锦
作者: July 、阿财。
时间:二零一一年十月十三日。
引言
无私分享造就开源的辉煌。
今是二零一一年十月十三日,明日 14 日即是本人刚好开博一周年。在一周年之际,特此分享出微软面试
全部 100 题答案的完整版,以作为对本博客所有读者的回馈。
一年之前的 10 月 14 日,一个名叫 July 的人在一个叫 csdn 的论坛上开帖分享微软等公司数据结构 + 算法
面试 100 题,自此,与上千网友一起做,一起思考,一起解答这些面试题目,最终成就了一个名为: 结构之法
算法之道 的 编程面试 与 算法研究 并重的博客,如今,此博客影响力逐步渗透到海外,及至到整个互联网。
在此之前,由于本人笨拙,这微软面试 100 题的答案只整理到了前 60 题(第 1-60 题答案可到本人资源下
载处下载: http://v_july_v.download.csdn.net/
http://v_july_v.download.csdn.net/
http://v_july_v.download.csdn.net/
http://v_july_v.download.csdn.net/ ),故此,常有朋友留言或来信询问后面 40 题的答案。只是
因个人认为: 一 、答案只是作为一个参考,不可太过依赖; 二 、常常因一些事情耽搁(如在整理最新的今年
九月、十月份的面试题: 九月腾讯,创新工场,淘宝等公司最新面试十三题 、 十月百度,阿里巴巴,迅雷搜狗
最新面试十一题 ); 三 、个人正在针对那 100 题一题一题的写文章,多种思路,不断优化 , 即成 程序员编程
艺术系列 。自此,后面 40 题的答案迟迟未得整理。且个人已经整理的前 60 题的答案,在我看来,是有诸多问
题与弊端的,甚至很多答案都是错误的。
互联网总是能给人带来惊喜。前几日,一位现居美国加州的名叫阿财的朋友发来一封邮件,并把他自己
做的全部 100 题的答案一并发予给我,自此,便似遇见了知己。十分感谢。
任何东西只有分享出来才更显其价值。本只需贴出后面 40 题的答案,因为前 60 题的答案本人早已整理上
传至网上,但多一种思路多一种参考亦未尝不可。特此,把阿财的答案再稍加整理番,然后把全部 100 题的答
案现今都贴出来。若有任何问题,欢迎不吝指正。谢谢。
上千上万的人都关注过此 100 题,且大都都各自贡献了自己的思路,或回复于 微软 100
100
100
100 题维护地址 上,或
回复于本博客内,人数众多,无法一一标明,特此向他们诸位表示敬意和感谢。谢谢大家,诸君的努力足以影
响整个互联网,咱们已经迎来一个分享互利的新时代。
微软面试 100
100
100
100 题全部答案
最新整理的全部 100 题的答案参见如下(重复的,以及一些无关紧要的题目跳过。且因尊重阿财,未作过
多修改。因此, 有些答案是有问题的 ,重点还可关注本人的 程序员编程艺术系列 ,亦可参考个人之前
整理的前 60 题的答案:第 1 题 -20 题答案: http://blog.csdn.net/v_JULY_v/archive/2011/01/10/6126406.aspx ,
第 21-40 题答案: http://blog.csdn.net/v_JULY_v/archive/2011/01/10/6126444.aspx ,第 41-60 题答案:
http://blog.csdn.net/v_JULY_v/archive/2011/02/01/6171539.aspx ):
1. 把二元查找树转变成排序的双向链表
题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ \
6 14
/ \ / \
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16 。

首先我们定义的二元查找树节点的数据结构如下:
struct BSTreeNode
{
int m_nValue; // value of node
BSTreeNode *m_pLeft; // left child of node
BSTreeNode *m_pRight; // right child of node
};
ANSWER:
This is a traditional problem that can be solved using recursion.
For each node, connect the double linked lists created from left and right child node to form a full list.
/**
* @param root The root node of the tree
* @return The head node of the converted list.
*/
BSTreeNode * treeToLinkedList(BSTreeNode * root) {
BSTreeNode * head, * tail;
helper(head, tail, root);
return head;
}
void helper(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:
Stack is a LIFO data structure. When some element is popped from the stack, the status will recover to the
original status as before that element was pushed. So we can recover the minimum element, too.
struct MinStackElement {
int data;
int min;
};
struct MinStack {
MinStackElement * data;
int size;
int top;
}
MinStack MinStackInit(int maxSize) {
MinStack stack;
stack.size = maxSize;

stack.data = (MinStackElement*) malloc(sizeof(MinStackElement)*maxSize);
stack.top = 0;
return stack;
}
void MinStackFree(MinStack stack) {
free(stack.data);
}
void MinStackPush(MinStack stack, int d) {
if (stack.top == stack.size) error( “ out of stack space. ” );
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 ++;
}
int MinStackPop(MinStack stack) {
if (stack.top == 0) error( “ stack is empty! ” );
return stack.data[--stack.top].data;
}
int MinStackMin(MinStack stack) {
if (stack.top == 0) error( “ stack is empty! ” );
return stack.data[stack.top-1].min;
}
3. 求子数组的最大和
题目:
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为 O(n) 。
例如输入的数组为 1, -2, 3, 10, -4, 7, 2, -5 ,和最大的子数组为 3, 10, -4, 7, 2 ,
因此输出为该子数组的和 18 。
ANSWER:
A traditional greedy approach.
Keep current sum, slide from left to right, when sum < 0, reset sum to 0.
int maxSubarray(int a[], int size) {
if (size<=0) error( “ error array size ” );
int sum = 0;
int max = - (1 << 31);
int cur = 0;
while (cur < size) {
sum += a[cur++];
if (sum > max) {
max = sum;
} else if (sum < 0) {
sum = 0;
}
}
return max;
}
4. 在二元树中找出和为某一值的所有路径
题目:输入一个整数和一棵二元树。
从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。
打印出和与输入整数相等的所有路径。
例如输入整数 22 和如下二元树
10
/ \
5 12
/ \
4 7

则打印出两条路径: 10, 12 和 10, 5, 7 。
二元树节点的数据结构定义为:
struct BinaryTreeNode // a node in the binary tree
{
int m_nValue; // value of node
BinaryTreeNode *m_pLeft; // left child of node
BinaryTreeNode *m_pRight; // right child of node
};
ANSWER:
Use backtracking and recurison. We need a stack to help backtracking the path.
struct TreeNode {
int data;
TreeNode * left;
TreeNode * right;
};
void printPaths(TreeNode * root, int sum) {
int path[MAX_HEIGHT];
helper(root, sum, path, 0);
}
void helper(TreeNode * root, int sum, int path[], int top) {
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:
This is a very traditional question...
O(nlogn): cat I_FILE
|
sort -n
|
head -n K
O(kn): do insertion sort until k elements are retrieved.
O(n+klogn): Take O(n) time to bottom-up build a min-heap. Then sift-down k-1 times.
So traditional that
I
don
’
t want to write the codes...
Only gives the siftup and siftdown function.
/**
*@param i the index of the element in heap a[0...n-1] to be sifted up
void siftup(int a[], int i, int n) {
while (i>0) {
int j=(i&1==0 ? i-1 : i+1);
int p=(i-1)>>1;
if (j<n && a[j]<a[i]) i = j;
if (a[i] < a[p]) swap(a, i, p);
i = p;
}
}
void siftdown(int a[], int i, int n) {
while (2*i+1<n){
int l=2*i+1;
if (l+1<n && 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 次 ....
以此类推 ..
ANSWER:
I
don ’ t like brain teasers. Will skip most of them...
第 7 题
微软亚院之编程判断俩个链表是否相交
给出俩个单向链表的头指针,比如 h1 , h2 ,判断这俩个链表是否相交。
为了简化问题,我们假设俩个链表均不带环。
问题扩展:
1. 如果链表可能有环列 ?
2. 如果需要求出俩个链表相交的第一个节点列 ?
ANSWER:
struct Node {
int data;
int Node *next;
};
// if there is no cycle.
int isJoinedSimple(Node * h1, Node * h2) {
while (h1->next != NULL) {
h1 = h1->next;
}
while (h2->next != NULL) {
h2 = h2-> next;
}
return h1 == h2;
}
// if there could exist cycle
int isJoined(Node *h1, Node * h2) {
Node* cylic1 = testCylic(h1);
Node* cylic2 = testCylic(h2);
if (cylic1+cylic2==0) return isJoinedSimple(h1, h2);
if (cylic1==0 && cylic2!=0
||
cylic1!=0 &&cylic2==0) return 0;
Node *p = cylic1;
while (1) {
if (p==cylic2
||
p->next == cylic2) return 1;
p=p->next->next;
cylic1 = cylic1->next;
if (p==cylic1) return 0;
}
}
Node* testCylic(Node * h1) {
Node * p1 = h1, *p2 = h1;
while (p2!=NULL && p2->next!=NULL) {
p1 = p1->next;
p2 = p2->next->next;
剩余45页未读,继续阅读















Gerigory
- 粉丝: 8
- 资源: 31
上传资源 快速赚钱
我的内容管理 收起
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助

会员权益专享
最新资源
- Xilinx SRIO详解.pptx
- Informatica PowerCenter 10.2 for Centos7.6安装配置说明.pdf
- 现代无线系统射频电路实用设计卷II 英文版.pdf
- 电子产品可靠性设计 自己讲课用的PPT,包括设计方案的可靠性选择,元器件的选择与使用,降额设计,热设计,余度设计,参数优化设计 和 失效分析等
- MPC5744P-DEV-KIT-REVE-QSG.pdf
- 通信原理课程设计报告(ASK FSK PSK Matlab仿真--数字调制技术的仿真实现及性能研究)
- ORIGIN7.0使用说明
- 在VMware Player 3.1.3下安装Redhat Linux详尽步骤
- python学生信息管理系统实现代码
- 西门子MES手册 13 OpcenterEXCR_PortalStudio1_81RB1.pdf
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈



安全验证
文档复制为VIP权益,开通VIP直接复制

评论7