# Google 面經
https://docs.google.com/spreadsheets/d/1vlrDFAauI2crzWhldcP0eCXqPU-RE3l4d_AFjbFJOiU/edit?usp=sharing
https://jobs.1point3acres.com/companies/google/interview
## VO
- https://www.1point3acres.com/bbs/thread-883437-1-1.html
1. 东南西北以及四个斜的 八个方向 比如1N2,2N3, 3S1就是说1在2的北边,2在3的北边。3在1的南边(也就是1在3的北边),代表着1->2, 2->3, 1->3,此时返回true,
Answer: 找circle。如果有circlereturn false。没circle return true
2. 建一个MyIter class。假设已经建好了trie(ABC → “he”, DE → “llo”), 。trie的leaf是一个string。MyIter class的constructor input是一个javaioreader和一个已经建好的Node root
Answer:
弄一个buildStr method,给你一个ABCDE这种String,返回在tire里面的leaf的string的concandinate → “Hello”
Iter class还要写出hasNext和next method。这里可以把之前建好的string在class里面存下来,然后用一个index去做。
follow up:因为给的Node的children 是个node array,如果换成hashmap会怎么样
follow up:如果换成换hashMap的down side是什么
follow up:在memory层面还能如何优化?
3. 有个startRouter, 有个endRouter,有个RouterLocation Array,有每个Router可以connect的range。
看是否可以从start connect to end
union find。遍历每个pair,然后union在一起,然后find startRouter, find endRouter. 看他们的parent是否一样。一样就说明可以从start到end
4. 第四题 Wrap text 有点像利口留疤但其实不是。
Wrap text.
A function which takes text and a width (int) and returns the number of lines that the text would take on the page.
Example:
text = "asdf asdf asdf asdf asdf asdf"
width = 7
answer: 6
Example:
text = "asdf asdf asdf asdf asdf asdf"
width = 8
answer: 6
Example:
text = "abcdabcdaabcdabcda \n\t asdf asdf(1) asdf asdf(1) asdf(1)"
width = 9
answer: 5
text = "asdf asdf asdff asdf asdf asdf"
width = 14
asdf asdf
asd asdsadsd
asdf asdf
text = "a a a a a a a a a a a a"
width = 16
answer = 2
a a a a a a
a a a a a a
text = "a a a a"
width = 12
s = s.trim();
split("\\s+")
After split
for each single string, we need to use it and width to get how many lines it take
*/
我开始以为是利口留疤就按照那个思路去做了。这题corner case巨多,我现在也有点忘了具体要求,只记得一个特别长的String是可以跨越多行的,然后两个String中间如果有多个空格也不像留疤那样要缩减成1一个。当时很勉强做出来了。
Follow up: Assume Part 1 getLines works perfectly.
Write a new function:
int getColumnTextSplit(String s, int width, int col);
if width = 10, col = 5
then we have two columns of width 5
width = 10, col = 2
two columns, width 2 and 8
returns the split point in s
text = "asdf1 asdf2 asdf3 asdf4 asdf5 asdf6"
width = 12
col = 6
asdf1 | asdf4
asdf2 | asdf5
asdf3 | asdf6
asdf1 | asdf2
| asdf3
| asdf4
| asdf5
| asdf6
这里的col是指在哪一个col开始分。通过这个col可以得到两个width。然后根据这两个width,再从原String里面切一刀,然后左面String根据width1,右面String根据width2,得到两个lines number。目标是这两个lines number尽可能的靠近。
没做出来,面试官最后说了可以用Binary Search。估计就给我down level在这一轮了。
- https://www.1point3acres.com/bbs/thread-883204-1-1.html
1st round. 技术面
cord tree, 可以看蠡口的讨论区cord
(a)对leaf, internal 分别定义一个类,后续实现用isInstance() 区分
(b)对给定的index,返回对应的字母 树的遍历即可,注意corner case,这里有被面试官提醒,不知道会不会扣分
(c)在(b)的基础上,对给定的index,输出index~index+L的字符串,还是树的遍历+path 记录
(d)time/space complexity
2nd round. 技术面
secret & guess 有点像 蠡口的二舅舅
secret:CHALK
guess: AGBLC
output: YRRGY
就是 如果字符存在且位置正确,G;字符存在但是位置不对,Y;否则 R
(a)secret 每个字符是unique,guess 也没有重复字符
(b)secret 每个字符是unique,guess 有重复字符 , 比如说 guess=“AGAIN”, output="RRGRR"
(c)secret 有重复,guess 有重复字符,我用了dictionary 记录count
(d)有一系列 guess 输入,让你比较每次的guess 是否有比上一次的guess 更好,没有implementation, 主要就在定义 何为“更好”。比如说 R->G 是一种improvement, 到这里我就有点云里雾里了 不知道在考察什么,然后就差不多到时间
3rd round. 技术面
snapshotarray....hhhhhhhh 正好周末刷到 蠡口瑶瑶撕溜
讨论区大佬用了binary search 和记录每个index 的 history record.
我自己用了个dictionary 记录每次的变化,但是空间复杂度有点高,最后follow up 我说了一下大佬的思路
4th round. BQ
一个笑眯眯的印度小姐姐。
就是一些 disagreement, conflicts, a happy experience, high goal
5th round. 技术面
filesystem, 也是个树结构,多叉树, 有dir, 有file, 然后file 有对应的filesize, 让你计算这个目录下的filesize 总和
(a)DFS 写了一个
(b)某些目录被多次访问,如何提高计算效率。用一个dict 记录
(c)BFS 又写了一个
(d)如果有cycle 怎么办,变成一个图的问题,用一个visited set 记录已经访问的节点
- https://www.1point3acres.com/bbs/thread-883080-1-1.html
楼主2/3年经验,面L4.
楼主大概运气不太好,先是Amazon店面一个corner case没考虑就被拒,再是Microsoft碰到两个Hard和一个黑人面试官(https://www.1point3acres.com/bbs/thread-880981-1-1.html),然后到🐶 onsite,四轮当中两轮hard,第二轮和第三轮的面试官还抽中同一题(我说了,第三轮换了一个题)。接下来只有meta了,其他的都没投进去,楼主现在是裸辞状态,真的有点郁闷。
=====
1. BQ。抢功劳的同事;紧急的deadline;unexpected problem。根据面试官的反馈,感觉还行。
2. 路由器题。输入是一堆路由器的(x, y, id),每个路由器可以给radius范围内的其他路由器发消息,给一个初始id,和一个结束id,问消息能否从初始路由器发送到结束路由器。follow-up是,路由器只能给radius范围内最近的路由器发信息,选最近的路由器发消息;如果一个路由器有好几个最近的路由器,给所有的最近路由器发消息。
我用O(n^2)建图+BFS解决所有,一直写写写,没怎么优化。这一题不知道怎样。
3. 实现一个class,在xy平面上,一开始没有点,不断add和remove点,点用坐标(x,y)表示,每一步return一个最小box把所有的点框住,box平行于x/y轴,要求每一步优于O(n)解法。
我propose一个x2ydictionary,对每个x对应的y,double linked list O(1) delete, O(k) insertion,接着在面试官的引导下,用BST存x,但是python没现成的BST。凉凉。面完觉得面试官想要BST of BST?我觉得是个Hard。
4. 面试官一开始想考上一题,不想重演上一题的灾难,后来改成manager/employee题:一个class,一开始为空,有三个method,setManager(M, E), M是E的direct manager,setPeers(E1, E2), E1和E2是peers,E1的direct manager不是E2的,queryManager(MM, E),问MM是否是E的manager,可以是很多层的manager。这三个method被call的顺序是随机的。
我的解法:dag表示manager-employee关系,udg表示peers关系,另外一个e2m字典,记录直接mgr,时间刚刚够写完,答了下时间复杂度。不知道怎样。
5. 霸一罢。一个车,初始速度为1,初始位置是0,两个指令,A速度加倍,R速度降为1位置不动。第一问,给一个instruction string,返回离初始位置的distance。第二问赛车本车,给最终距离,返回最短指令序列。
抽到这题心里就拔凉,知道第二问要dp,解法没太看明白。第一问写完问了时间复杂度,dry run with AARA。第二问尝试用那个dp解,没写完,事后后悔没用BFS写个brute-force。
四个题两个题考到盲点,上周四微软碰到两个hard一个黑人面试官,面完就有点自闭。今天面完更自闭了。亚麻和🐶家放大水为啥放不到我身上?
- https://www.1point3acres.com/bbs/thread-882935-1-1.html
第一轮:BFS, 问了time, space complexity 和几个follow up question,感觉不错。答完了时间多跟面试官还聊了聊
第二轮:问top n user的名字和wordCnt。楼主刚开始走了弯路用了sorting,后来面试官问有没有更快的方法,改成了Priority Queue。健谈白人大叔,还有一个shadow的人,聊的蛮开心的,就不知道这弯路会不会影响评分。
第三轮:滑轨的一轮。面试官是个韩国小哥。在地里看过类似的题但没当时没细看,现在追悔莫及。题目大概是告诉你一堆点之间的相对关系(八个方向)。问这是不是valid。比如1 N 2, 2 N 3, 3 N 1, 那output 就是invalid。我说detect cycle他说对这是正确思路。然后写了code,但没写完时间就到了。没有follow up question。这一轮应该是no hire了
第四轮:遇到国人里。问题是也在地里遇到的fun city question。楼主再一次没有细看(后悔ing)。后来用bfs找所有长为4的路径写了个complexity很高的code,楼主感觉要挂。面试结束楼主还不死心问了下optimal solution怎么解,就是下面链接楼主的解法。国人面试官很nice的表示我的solution work,他45分钟也写不出optimal的,马上写出optimal的他都默认以前做过原题。谢谢他的安慰了。
是这楼主里的第二题。https://www.1point3acres.com/bbs/thread-827588-1-1.html
第五轮:BQ 一些简单的问题,面试官感觉是俄罗斯大叔
- 处理people in different background
- 如果deadline但你的product不完美怎么办
- 你过去最满意的一个project
大叔人非常nice。听说这是最后一轮了就问我有什么问题都可以问他,时间很多。最后跟他聊google的team和cultural比预期多聊了二十多分钟。
感觉HC基本过不了了,也是一次难得的体验吧。LC总共做了不到10题所以也不知道有没有对应的。
https://www.1point3acres.com/bbs/thread-882904-1-1.html
补充内容 (2022-04-12 20:42 +8:00):
更正:manager/employee那题,setPeers(E1,E2),E1的direct manager是E2的,如果E1是C的manager,E2不是C的manager
## Phone
- https://www.1point3acres.com/bbs/thread-879616-1-1.html
## VO
- 150 x2 follow up是如何判断input valid,整体很不错
- 1293 (not shortest but yes or no)
- 212
- 843 + Worlde
- 986
- 给黄绿两种颜色的布,给定黄色布的位置,比如[1,3], [5,8], [9,15],剩下所有位置都可以认为是绿色的布。input:黄色布的位置list,一块绿色布的长度。问:把绿色布放到任意位置,最多能剩多少黄色布。
- 匹配足球比赛,给定1.国家和足球队的dict(e.g. {'Italy': [c1, c2], 'Spain': [c3], 'France': [c4, c5, c6]) 2. 之前踢过比赛的队[c3, c6], [c4, c2], [c5, c1],要求匹配下一轮的n场比赛(任意一种组合),要求同一个国家的不能一起比,之前踢过比赛的队也不能一起比。
- 366 follow up是,如果一个node没有任何leaf node,这个node就必须马上删除,no matter还有没有其他leaf node
- 给一个string,类似aaabbc的形式,就是相同的char都放在一起,不会有aba这种形式的,输出出现次数最多的那个char 用tow pointer follow up是怎么优化space和time complexity
- **写两个function,第一个function是插入一段interval和相应的一个operator name,判断能不能插入,可以的话分配一个不重复的id并且返回这个id,第二个function是用id找一个operator,如果存在这个id,就把相应interval删除,如果存在这个interval,删除成功,返回true,如果不存在,返回false 用的treemap,但是没能全写完,所以没follow up**
- 给一个integer array,找到一个subsequence,在这个subsequence里,后一个element总比前一个大1,输出它的长度 follow up是,如果要求的是在subsequence里,后一个element比前一个大的范围是1 ~ N,给出最长的subsequence
```cpp
#include "print.h"
#include <vector>
void getLongestSubsequence(const vector<int> &A, vector<int> &ans, int N = 1) {
const auto n = A.size();
// dp[i] := # of longest subseqs. that ends at A[i]
vector<int> dp(A.size(), 1);
// prev[i] := prev index of i
// A = [1 3 2 3]
// dp = [1 1 2 3]
// prev = [x x 0 1]
vector<int> prev(A.size(), -1);
for (auto i = 0; i < A.size(); ++i) {
for (auto j = i + 1; j < A.size(); ++j) {
// if (A[j] == A[i] + 1) {
if (A[j] > A[i] && A[j] <= A[i] + N) {
if (dp[i] + 1 > dp[j]) {
// find a better solution
dp[j] = dp[i] + 1;
prev[j] = i;
}
}
}
}
const auto it = std::max_element(begin(dp), end(dp));
const auto max_index = it - begin(dp);
const auto max_length = dp[max_index];
ans.reserve(max_length);
// start from max_index -> going backward
auto buildAns = [&prev, &ans, &A](int i) {
while (i != -1) {
ans.push_back(A[i]);
i = prev[i];
}
std::reverse(begin(ans), end(ans));
};
buildAns(max_index);
}
int main() {
vector<int> A{1, 3, 2, 3};
vector<int> B{1, 4, 2, 7, 8};
vector<int> ans;
// getLongestSubsequence(B, ans);
getLongestSubsequence(B, ans, 3);
print(ans);
}
```
- 给的题目是地里传纸条变体。原题是比较复杂的DP但感觉最近咕咕放水给改成一个纯math计算概率的题目了。计算概率公式搞清楚单纯遍历path就可以做出来,但因为抗抑郁药副作用比较大打字手抖还慢导致没写完...
- https://www.1point3acres.com/bbs/thread-878219-1-1.html
- Nary-tree的先序遍历变体并打印。一开始说回溯做但面试官表示用不着太麻烦了用递归遍历
- https://www.1point3acres.com/bbs/thread-877866-1-1.html
- 有一个店, T[N] , 表示N 个服务员和 他们服务一个人的时间(每个服务员只能同时服务一个顾客)。店刚开门,前面有M 个人在等着,这个时候来一个新顾客, 问他要等多长时间
- 一个pq就可以把,存的是服务员的开始服务时间和持续时间,每次弹出来最早且最快的,然后开始时间+=持续时间重新放回,重复m次,第m+1次取出来的开始时间就是需要他等待的时间
- 时间范围是 0 -minT[N] * M, 定义一个函数check 在时间t内能不能服务完 M个客人?
- 636 要格式化打印出每一步正在运行的函数。 当一个函数A start之后,如果没结束,再start另一个函数B,那么B就是A的子函数。如果再来个C,D,E类似的,这时候要打印:
- 给一堆坐标点,找里面面积最大的一条边平行于X轴的平行四边形。
- https://www.1point3acres.com/bbs/thread-877541-1-1.html
- 1167
- 1143
- 44
- 460
- https://www.1point3acres.com/bbs/thread-877053-1-1.html
- bike: 1057 1066
- https://www.1point3acres.com/bbs/thread-876745-1-1.html
- 输入一串两个点的名称和坐标位置关系,返回是否存在这样的位置关系(即是否有矛盾的)
例如[1 NE 2, 2 SE 3, 3 W 1]
返回true
解释:1在2的东北方,2在3的东南方,3在1的西方,空间上合理
- 给一个每个人的进出时间输出每段时间有哪些人
A,1,5
B,2,4
输出
1,2,A
2,4,AB
4,5,B
这个面试前正好在面经里看到了,是这个解法:把所有人的开始和结束全部作为事件,扔到一个list里面然后排序,然后拿个set一类的存一下当前有哪些人。类似飞机起落题目
- 是给一串String和dictionary,String是一句话,里面有错的词,正确的词在dictionary里,让你correct
input: Todxy is a god day.
dictionary: today, good
output: Today is a good day
先开始说dictionary是map有一一对应,之后问没有对应只有正确的单词的话怎么办,这里用edit distance
- 2096
- https://www.1point3acres.com/bbs/thread-875971-1-1.html
- 地里出现过的find all bad versions.
给定input数组,相邻的version只能一样bad,或者右侧的version比左侧的version更bad。同时给定一个helper function,input两个不同的version number ,假定为v1,v2,output是两个version时候一样bad,或者v2比v1更bad(假定v1 < v2)。
Lz先口头说了一下暴力解,然后用recursive binary search解出来了。需要注意的是recursive binary search最极端情况下时间复杂度也会达到O(n).
- 给一个二叉树,每个节点都有一个value值,求二叉树中相邻的K个节点所有value可以构成的maximum sum。
Lz的思路是dfs的同时,对于每个节点返回一个数组,数组的index对应 的值是该节点和其子树中任意节点(共index个节点)所能构成的maximum sum。这样只需要遍历所有节点一遍就可以得到最终结果。
- 1153
- https://www.1point3acres.com/bbs/thread-874886-1-1.html
- 已知有一个类, 有两个function可以调用, hasNext(), 和 getNext() 分别输出是否有下一个, 和得到下一个char.
假设已知这个类的两个实例, it1,和it2, 让我们来比较两个类的大小。
例子: it1 = 34.12345789
it2 = 34.12346
如果 it1 < it2: return 1
或者 it1 == it2: return 0
或者 it1 > it2: return -1
- There is a ball on the nth stairs, and it wants to get to the ground(level 0).
During odd time, you can jump down 1, 2 stairs. During even time, you can jump down 2, 3 stairs.
Return the number of ways you can get to ground.
第二题可以把一个stair拆成两个stair,一个odd time stair,一个even time stair,然后再DP。LC70的变种。
