avatar
R*9
1
M面经
两个月前面的,乘着记得回报本版。
Phone: lowest common ancestor of two nodes in a binary tree. Binary tree
node doesn’t have parent pointer.
What if the nodes have parent pointer?
Onsite:
1. Print the boundary of binary tree anti-clockwise.
2. a. Given a linked list, put all the even numbers before odd numbers.
e.g. 3->4->2->7->null
should become 4->2->3->7->null
b. A small design problem. Shuttle is picking up passages on a lane. The
arrival of passengers are random. Design such a system.
3. Find the number of valid phone numbers such that each digit and its
following digit should be a knight move in chess.
1 2 3
4 5 6
7 8 9
* 0 # 电话号码十位数,每位(除了最后一位)和它的下一位要满足 chess 中
knight 的条件。例如 16, 18, 27, 29 … 先写了一个backtracking, 面试官不满意,
说我的复杂度高了,他要DP的答案。于是写了个DP,面试官表示满意。
4. 面试官在手机上浏览一个网页,貌似是关于C++特性的一个网站。他问了五六个
C++性质的问题,到了 diamond problem, virtual inheritance 的时候不会了。
他讲解了一番,然后说,我们C++到此为止,开始做题吧。这个时候感到自
己大概要挂了,以前光顾着刷题没有看基础知识了 >.<
题目是 reverse words in a string. 反转后第N个单词后的空格数要等于远string中
第N个单词后的空格数。
e.g. Print Hello World
World Hello Print
我一直在想 inplace 的解法,但是没有想出来,问可以写一个不考虑空格数的。
于是写了一个常见的算法,反转整个str, 再反转每个单词。这样的结果是
World Hello Print
面试官说,我们可以用一个数组把空格数存起来,再shift words in the resulting
string. 我比较郁闷了,如果能用额外空间的话何必这么麻烦呢?直接开辟一块和
原来string大小相同的空间,用三个指针,其中一个从前往后扫,专门扫空格数,其他
两个指针从后往前扫,专门找单词。把找到的单词和空格数放到新的空间中就好了。好
吧,我就说你的方法挺好的,我没有想到。。。
5. behavior question 和一道小的设计题。
三天后,recruiter 来电,说基础知识不够好,我申请的职位高了。。。
avatar
h*e
2
谢谢楼主 感觉 翻转单词数字什么的微软经常考,楼主拿到G家要恭喜的。
avatar
R*9
3
谢谢 ^-^

【在 h*******e 的大作中提到】
: 谢谢楼主 感觉 翻转单词数字什么的微软经常考,楼主拿到G家要恭喜的。
avatar
h*e
4
这个到了晚上了 讨论一下, binary tree boundary怎么实现的吧。 dfs 然后用个arr
[depth][2]的数组存起来还是怎样阿。
avatar
s*i
5
mark
avatar
h*e
6
lz binary tree boundary 是怎么定义的阿, 树中间镂空算不算阿。

【在 R******9 的大作中提到】
: M面经
: 两个月前面的,乘着记得回报本版。
: Phone: lowest common ancestor of two nodes in a binary tree. Binary tree
: node doesn’t have parent pointer.
: What if the nodes have parent pointer?
: Onsite:
: 1. Print the boundary of binary tree anti-clockwise.
: 2. a. Given a linked list, put all the even numbers before odd numbers.
: e.g. 3->4->2->7->null
: should become 4->2->3->7->null

avatar
R*9
7
first print the left boundary, then all the leaves, and the right boundary.
1
2 3
4 5 6
7 8 9
should be 1 2 4 7 8 9 6 3.
void traverse(Node* root, bool left_most, bool right_most)
{
if (!root) return; // bottom condition
if (left_most) cout << root->val << ' '; //先序打印左边界

traverse(root->left, left_most, false);
if (!root->left && !root->right && !left_most && !right_most) cout <<
root->val << ' '; //中叙打印叶子
traverse(root->right, false, right_most);
if (right_most && !left_most) cout << root->val << ' '; //后序打印右
边界
}
void traverse(Node* root)
{
traverse(root, true, true);
}
left_most, right_most 表示 root 是否在该层的左边界或是右边界

【在 h*******e 的大作中提到】
: lz binary tree boundary 是怎么定义的阿, 树中间镂空算不算阿。
avatar
h*e
8
这样的话,看代码的意思, 镂空的内沿就不算了,题目主要让计算左边,右边 加上叶
子节点 。楼主leftmost rightmost两个 状态参数用得好,这样就inplace 一次遍历成
功结果也不用在外面存了。谢谢楼主。

【在 R******9 的大作中提到】
: first print the left boundary, then all the leaves, and the right boundary.
: 1
: 2 3
: 4 5 6
: 7 8 9
: should be 1 2 4 7 8 9 6 3.
: void traverse(Node* root, bool left_most, bool right_most)
: {
: if (!root) return; // bottom condition
: if (left_most) cout << root->val << ' '; //先序打印左边界

avatar
w*w
9
mark
avatar
R*9
10
😄 我刚开始写了三个分开的函数,从跟节点找最小值,中序打印叶子,从跟节
点找最大值但用后序打印。后来面试官让写成一个函数才想到的。
BTW,什么是镂空内沿啊?

【在 h*******e 的大作中提到】
: 这样的话,看代码的意思, 镂空的内沿就不算了,题目主要让计算左边,右边 加上叶
: 子节点 。楼主leftmost rightmost两个 状态参数用得好,这样就inplace 一次遍历成
: 功结果也不用在外面存了。谢谢楼主。

avatar
h*e
11
http://en.wikipedia.org/wiki/Binary_tree
比如上个binary tree wiki 中右图示例,图凹进去的部分 4 9 5 2 7 6 11 是个大镂空
的凹陷。 看起来这个题算boundary,不包括凹陷的内沿 4 9 5 2 7 6 11。

【在 R******9 的大作中提到】
: 😄 我刚开始写了三个分开的函数,从跟节点找最小值,中序打印叶子,从跟节
: 点找最大值但用后序打印。后来面试官让写成一个函数才想到的。
: BTW,什么是镂空内沿啊?

avatar
R*9
12
I see. Thanks~

镂空

【在 h*******e 的大作中提到】
: http://en.wikipedia.org/wiki/Binary_tree
: 比如上个binary tree wiki 中右图示例,图凹进去的部分 4 9 5 2 7 6 11 是个大镂空
: 的凹陷。 看起来这个题算boundary,不包括凹陷的内沿 4 9 5 2 7 6 11。

avatar
l*8
13
left_most, right_most这个思路不错,学习了。
还可以简化一下:
void traverse(TreeNode * root, bool leftMost = true, bool rightMost = true) {
if (!root) return;
if (leftMost || (!rightMost && !root->left && !root->right))
print(root);
traverse(root->left, leftMost, false);
tarverse(root->right, false, rightMost);
if (rightMost && !leftMost)
print(root);
}

【在 R******9 的大作中提到】
: first print the left boundary, then all the leaves, and the right boundary.
: 1
: 2 3
: 4 5 6
: 7 8 9
: should be 1 2 4 7 8 9 6 3.
: void traverse(Node* root, bool left_most, bool right_most)
: {
: if (!root) return; // bottom condition
: if (left_most) cout << root->val << ' '; //先序打印左边界

avatar
R*9
14
确实是,遍历叶子不需要 inorder

) {

【在 l*********8 的大作中提到】
: left_most, right_most这个思路不错,学习了。
: 还可以简化一下:
: void traverse(TreeNode * root, bool leftMost = true, bool rightMost = true) {
: if (!root) return;
: if (leftMost || (!rightMost && !root->left && !root->right))
: print(root);
: traverse(root->left, leftMost, false);
: tarverse(root->right, false, rightMost);
: if (rightMost && !leftMost)
: print(root);

avatar
r*k
15
太牛了

【在 R******9 的大作中提到】
: first print the left boundary, then all the leaves, and the right boundary.
: 1
: 2 3
: 4 5 6
: 7 8 9
: should be 1 2 4 7 8 9 6 3.
: void traverse(Node* root, bool left_most, bool right_most)
: {
: if (!root) return; // bottom condition
: if (left_most) cout << root->val << ' '; //先序打印左边界

avatar
f*n
16
mark
avatar
y*n
17
我也觉得很牛, 微软看来门槛很高。。

【在 r*******k 的大作中提到】
: 太牛了
avatar
x*u
18
mark
avatar
f*n
19
mark
相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。