---
# System prepended metadata

title: Google 面經

---

# 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
asd‍‍‌‌‍‌‌‍‌‌‌‍‍‍‍‌‍‍‍f3 | 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的变种。
![](https://i.imgur.com/S43AewA.jpg)
