HackTheRounds Interview Experiences

Google Software Engineer VO Interview Experience (2026) - Rental Fleet Planning & BST to DLL, Offer

Google SWE 2 round VO writeup: rental fleet capacity planning sweep line, max product subarray, BST to sorted circular doubly linked list, plus two convincing a

By Anonymous · 2026-03-19

Background

Got the Google SWE VO scheduled the week after my recruiter confirmed I had cleared the phone screen. I'm coming from a mid-size B2B SaaS with about 4 years of backend work, mostly Java + some Python for data tooling. This was my second Google loop ever (I bombed the first one two years ago on a graph problem I completely misread), so I was determined to actually prepare the things Google looks for instead of mass-grinding lists. Two rounds, back to back, and I walked out thinking I had actually done okay. A week later the recruiter confirmed.

Timeline

Total: about 9 weeks.

VO Format

Two 45-minute rounds with 15 minutes between them, both on Google Meet plus the shared doc. No Collabedit, no fancy IDE. You type into a Google Doc, they watch, nobody compiles anything. Get comfortable writing code without a linter telling you when you miss a semicolon.

Round 1: Coding — Rental Fleet Capacity Planning

Problem: Given last year's complete set of rental orders (each order has a pickup timestamp and a return timestamp), find the minimum number of vehicles needed to satisfy every order, and produce one valid assignment of vehicles to orders. A returned vehicle can be re-used immediately for a pickup at the same timestamp.

The interviewer was a senior engineer out of the Mountain View office, very calm, led with a few minutes of small talk about my team's infra stack. Once we got into the problem I had to resist the urge to jump straight at the answer. I had seen the "minimum meeting rooms" flavor before, so the minimum-vehicles piece was familiar. What I had not seen was the second half: actually assign specific vehicles.

My approach:

  1. Convert every order into two events: `(pickup_ts, +1, order_id)` and `(return_ts, -1, order_id)`.
  2. Sort events by timestamp. Ties: process returns before pickups, so a car that drops off at `t` can be re-rented at `t`.
  3. Sweep the events. Maintain a "free pool" of vehicle IDs. On a return event, push that order's vehicle back into the pool. On a pickup, if the pool is non-empty pop from it, otherwise mint a new vehicle ID.
  4. The answer for minimum vehicles is the highest vehicle ID ever minted.

I walked through the tie-break carefully because I know Google likes you to justify ordering. If you process pickups first on a tie, you under-count returns that should have freed a car. The interviewer nodded and we moved on.

Time: O(n log n) for the sort. Space: O(n) for events plus the free pool.

Follow-up: Given two rental windows [s1, e1] and [s2, e2] , do they overlap? This is actually deeper than it sounds because you have to agree on whether e1 == s2 counts. I said "in our problem, e1 == s2 is not an overlap because we already decided returns process before pickups," and that was the answer he wanted. He had one person argue it the other way in a previous loop and stall on this for ten minutes.

Practice it: [[problem/630?company=1|Meeting Rooms III Variant]]

Round 2: Behavioral + Two Coding

This round was a bundle. About 10 minutes of behavioral first, then two coding problems back to back.

Behavioral

Two prompts:

  1. Tell me about a time you convinced a team to adopt a technical approach they were initially skeptical of.
  2. Tell me about a time you identified a technical risk early and what you did about it.

I had two STAR stories ready. For the first I used a DB migration where I pushed us off a legacy Postgres trigger pattern onto an outbox table. I emphasized the part where three people disagreed with me and I set up a two-week test fork to prove out the numbers before we committed. For the risk prompt I used a case where I flagged a deadlock pattern during a design review that nobody else had caught, and we ended up rewriting the lock ordering. Specific numbers matter here: I said "the outbox migration cut our replay latency from 12 seconds p99 to 400ms" because vague wins do not land.

Coding 1: Maximum Product of a Contiguous Subarray

Problem: Given an integer array (can include negatives and zero), return the maximum product of any contiguous non-empty subarray.

Classic. The trick is that because of negative numbers, the biggest product up to position i can come from multiplying a small negative by another negative earlier. So you track both the running max and the running min, update them together at each step by considering the current element alone and the two extended products, and take the best running max as the answer.

O(n) time, O(1) space. I wrote it quickly and the interviewer asked me to walk through the [-2, 3, -4] test case by hand to prove I understood why we track cur min . He also asked what happens on all-zero input, and I said the invariant still holds because both cur max and cur min become zero and the answer collapses to zero.

Coding 2: BST to Sorted Circular Doubly Linked List (In-Place)

Problem: Given a BST, convert it in place into a sorted circular doubly linked list. The left pointer should point to the predecessor and the right pointer to the successor. Head's left should be tail, tail's right should be head.

Inorder traversal gives you the node sequence you want. The trick is threading the pointers during the traversal without materializing an explicit list. Keep a single mutable prev pointer (I used a class attribute to sidestep Python's closure rebinding quirks). On every visit, link prev and the current node both directions, then advance prev . At the very end, close the circle between head and the final prev .

O(n) time, O(h) stack space. Naming the invariant out loud (" prev is always the previous inorder node, or null before the first visit") made the code write itself.

Follow-ups:

  • What if you cannot modify the original tree's pointers? I said I would allocate new nodes mirroring the values and thread those, at the cost of O(n) extra space.
  • What if you need the list in descending order instead? Reverse inorder: right, root, left. Same pattern, just flipped.

Result

The recruiter called the following Friday afternoon. L4 offer, Sunnyvale. Team matching happened over two weeks and I landed on an infra team that owned parts of the storage stack, which was the area I had targeted from the start. Numbers were within about 5% of levels.fyi median for L4 with my experience.

Tips

  1. For the sweep line family, always justify your tie-break rule out loud. Whether you process returns before pickups at the same timestamp is the entire problem. Stating it explicitly shows the interviewer you thought about boundary conditions before they asked.
  2. Practice writing in a Google Doc with no syntax help. Yes, really. Open one and write Python for 20 minutes. Missing brackets and misspelled function names look unprofessional in a live doc, and you will make them if you have never practiced.
  3. Memorize two behavioral stories that map to five prompts. For each story know three numbers: scale, before-metric, after-metric. Every Google BQ round I know of asks for either a persuasion moment, a risk moment, a conflict moment, a failure moment, or an impact moment. A good story hits three of those with small tweaks.
  4. For "convert tree to linked list" style problems, keep `prev` as an instance attribute. Don't fight with Python's closure scoping under interview pressure. A single `self.prev` reads cleaner than a list wrapper or a `nonlocal`.
  5. Max Product Subarray: walk through `[-2, 3, -4]` by hand when asked. Interviewers give that exact input specifically to check you understand why you track two quantities. Have the trace memorized.
  6. Two 45-minute rounds is less time than it sounds. Plan for 10 minutes understanding, 5 for edge cases, 20 coding, 10 follow-up. If you are not coding by the 15 minute mark in a round, you are behind.