Google biggest difference between SDE VO Coding and other programs is that follow-up will continue to follow. A question can change from simple to complex. The test is whether you can adjust your thinking in real time as the question changes. This article is a complete review of the two questions I encountered, including the problem-solving process of each level of follow-up.

Topic 1: Log processing
Basic questions
Process a batch of logs. Each log contains timestamp and message content. The requirements are:
- Deduplication (use message content as unique identifier)
- Sort by timestamp in ascending order
- Output results
Problem-solving ideas:
Use a hash table to record the content of messages that have appeared, and sort them by timestamp after deduplication.
Def process_logs(logs):
# logs: [(timestamp, message), ...]
seen = {}
for timestamp, message in logs:
if message not in seen:
seen[message] = timestamp
# Sort by timestamp in ascending order
result = sorted(seen.items(), key=lambda x: x[1])
return [(ts, msg) for msg, ts in result]
Pitfalls:
This question is most easily misled by "original order". After deduplication, the data must be sorted by timestamp, not output in the order of input. During the interview, first confirm the ranking basis with the interviewer.
Follow-up 1: Keep the one with the largest timestamp
After deduplication, the same message content appears multiple times, and the one with the largest timestamp is retained.
Def process_logs_keep_latest(logs):
seen = {}
for timestamp, message in logs:
if message not in seen or seen[message] < timestamp:
seen[message] = timestamp
result = sorted(seen.items(), key=lambda x: x[1])
return [(ts, msg) for msg, ts in result]
The change is very small. You only need to add a conditional judgment when updating the hash table and keep the one with a larger timestamp.
Follow-up 2: Real-time data flow, collecting and outputting ordered results at the same time
Data is no longer provided all at once, but flows in in real time, requiring ordered results to be output while receiving.
Idea:
Use the min heap to maintain the current ordered results. Every time new data comes in and is deduplicated, it is inserted into the heap. The top of the heap is always the one with the smallest timestamp.
Import heapq
class LogProcessor:
def __init__(self):
self.seen = {}
self.heap = [] # (timestamp, message)
def add_log(self, timestamp: int, message: str):
if message in self.seen:
return # Remove duplicates and ignore them directly
self.seen[message] = timestamp
heapq.heappush(self.heap, (timestamp, message))
def get_next(self):
if self.heap:
return heapq.heappop(self.heap)
return None
Follow-up question: If the de-redefinition is to keep the latest one, how to change it in streaming?
The old data in the heap needs to be lazily deleted - when new data is inserted, the old data is marked as invalid, and when it is popped out, it is judged whether it is valid.
Question 2: How many lines does the text occupy?
First level: no line breaks
Given a string and the width of the text box, calculate how many lines the text occupies. There are no newlines in the string.
Simply divide the total length by width and round up:
Import math
def count_lines(text: str, width: int) -> int:
if not text:
return 0
return math.ceil(len(text) / width)
For example, length 10, width 3, the result is 4 lines.
Second level: join \n
There is in the string \n, wrap directly when encountering a newline character.
模拟显示过程,维护当前行数和当前行已放的字符数:
Def count_lines_with_newline(text: str, width: int) -> int:
lines=1
current = 0
for ch in text:
if ch == '\n':
lines += 1
current = 0
else:
current += 1
if current > width:
lines += 1
current = 1 # put the current character on a new line
return lines
Pitfalls:
After the line break, current returns to zero, but if the line break exceeds the width and the current character needs to be placed on a new line, current should start from 1, not 0.
The third level: two-column table
Upgrade to a two-column table. Each row has two left and right cells. The total width is fixed. You need to find the left and right width allocation that minimizes the height of the entire table.
Idea:
Enumerate left column width, right column width = total width – left column width. For each type of allocation, calculate the height of the left and right paragraphs of text respectively, take the maximum left and right height of each line, and find the allocation plan with the smallest total height.
Def min_table_height(left_text: str, right_text: str, total_width: int) -> int:
best = float('inf')
best_left_width = 1
for left_width in range(1, total_width):
right_width = total_width - left_width
left_height = count_lines_with_newline(left_text, left_width)
right_height = count_lines_with_newline(right_text, right_width)
#The table height takes the maximum value of the two columns
table_height = max(left_height, right_height)
if table_height < best:
best = table_height
best_left_width = left_width
return best
Follow-up question: What if there are multiple rows? Each row has left and right cells?
Def min_table_height_multi_row(rows: list, total_width: int) -> int:
# rows: [(left_text, right_text), ...]
best = float('inf')
for left_width in range(1, total_width):
right_width = total_width - left_width
total_height = 0
for left_text, right_text in rows:
left_h = count_lines_with_newline(left_text, left_width)
right_h = count_lines_with_newline(right_text, right_width)
total_height += max(left_h, right_h)
if total_height < best:
best = total_height
return best
Google VO coding has several things in common:
Each question will start with a simple version and then continue to add restrictions. Don’t rush to optimize after completing the basic version. Wait for the interviewer to give you a follow-up before deciding whether to change the structure.
It is best to reuse the previous functions for each layer of follow-up. The interviewer is looking at your code organization ability. The third-level table question directly called the second-level count_lines function, and he was very satisfied. When encountering "sorting" or "order" type questions, first ask what the sorting basis is, and don't make assumptions on your own.
There were two classmates around me who applied to Google at the same time. One prepared it himself and the other searched for it. ProgramHelp Make VO assists. Prepare yourself for that second round stuck in follow-up and fail. After finding an assist, the whole process went smoothly, and now he has joined the job. It’s not that you can’t prepare yourself, but Google’s follow-up direction is too difficult to predict. With North American CS experts on hand to give you ideas in real time, the error tolerance rate is much higher.