Solve graph path, interval deletion, and robbery
Company: Databricks
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: Medium
Interview Round: HR Screen
Quick Answer: This interview question evaluates algorithm design, data structures, correctness, complexity, edge cases, and implementation details in a realistic interview setting. A strong answer for Solve graph path, interval deletion, and robbery states assumptions, handles edge cases, explains trade-offs, and shows how to validate the result clearly.
Part A — Minimum-Time Path with Allowed Transport Modes
Constraints
- 1 <= n <= 10^4 (number of nodes)
- 0 <= number of edges <= 10^5
- 0 <= u, v, s, t < n
- 1 <= time <= 10^6 (edge weights are positive)
- mode is one of a small fixed label set (e.g. walk/bus/subway/bike)
- The graph is directed; edges not in allowed_modes are ignored entirely
Examples
Input: (4, [[0,1,5,'walk'],[0,2,2,'bus'],[2,1,1,'bus'],[1,3,4,'subway'],[2,3,10,'walk']], ['bus','subway'], 0, 3)
Expected Output: 7
Explanation: Allowed = {bus, subway}. Path 0->2 (bus, 2) -> 1 (bus, 1) -> 3 (subway, 4) = 7. The 2->3 'walk' edge is filtered out.
Input: (4, [[0,1,5,'walk'],[0,2,2,'bus'],[2,1,1,'bus'],[1,3,4,'subway'],[2,3,10,'walk']], ['walk'], 0, 3)
Expected Output: -1
Explanation: With only 'walk' allowed, the only walk edge from 0 is 0->1, but 1->3 is 'subway' (disallowed) and 2->3 walk is unreachable. No valid path ⇒ -1.
Input: (3, [[0,1,3,'walk'],[1,2,4,'walk']], ['walk','bus','subway','bike'], 0, 2)
Expected Output: 7
Explanation: All modes allowed (no restriction): plain Dijkstra. 0->1->2 = 3 + 4 = 7.
Input: (1, [], ['walk'], 0, 0)
Expected Output: 0
Explanation: Source equals destination with no edges: distance is 0.
Input: (5, [[0,1,1,'bike'],[1,2,1,'bike'],[0,2,10,'bike'],[2,3,1,'bus'],[3,4,1,'bus']], ['bike','bus'], 0, 4)
Expected Output: 4
Explanation: Cheaper to take 0->1->2 (bike, 1+1) than the direct 0->2 bike edge of 10, then 2->3->4 (bus, 1+1). Total 4.
Input: (2, [[0,1,7,'subway']], ['walk'], 0, 1)
Expected Output: -1
Explanation: The only edge is 'subway' but only 'walk' is allowed ⇒ t unreachable ⇒ -1.
Hints
- Non-negative edge weights ⇒ Dijkstra. Filter edges by allowed mode while building the adjacency list so the search never touches a disallowed edge.
- Use a min-heap keyed on accumulated time and the classic 'pop, skip-if-stale (d > dist[u]), relax neighbors' loop. You can early-exit the moment you pop t.
- Edge case: s == t returns 0 even with no edges. If t is unreachable under the allowed modes, dist[t] stays infinite ⇒ return -1.
Part B — House Robber on a Circle
Constraints
- 0 <= n <= 100
- 0 <= nums[i] <= 1000
- House 0 and house n-1 are adjacent (cannot both be robbed)
- Empty input returns 0; a single house returns nums[0]
Examples
Input: ([2,3,2],)
Expected Output: 3
Explanation: Cannot rob house 0 and house 2 (adjacent on the circle), so robbing both 2's is illegal. Best is house 1 alone = 3.
Input: ([1,2,3,1],)
Expected Output: 4
Explanation: Rob house 0 (1) and house 2 (3) = 4. House 0 and house 3 are adjacent but we don't pick both.
Input: ([0],)
Expected Output: 0
Explanation: Single house with 0 cash.
Input: ([5,1,1,5],)
Expected Output: 6
Explanation: Houses 0 and 3 are adjacent on the circle, so you can't take both 5s. Best non-adjacent pick is 5 + 1 = 6 (house 0 + house 2, or house 1 + house 3).
Input: ([],)
Expected Output: 0
Explanation: No houses ⇒ 0.
Input: ([1,2],)
Expected Output: 2
Explanation: Two houses are adjacent both ways on a 2-circle; rob the larger one = 2.
Input: ([200,3,140,20,10],)
Expected Output: 340
Explanation: Rob house 0 (200) and house 2 (140) = 340; house 0 and house 4 are adjacent so house 4 is excluded when house 0 is taken.
Hints
- Break the circular constraint by reducing to the linear House Robber problem twice: once over houses [0 .. n-2] (excluding the last) and once over [1 .. n-1] (excluding the first). The answer is the max of the two.
- Linear House Robber is a 2-variable DP: for each house, curr = max(curr, prev + nums[i]); then shift prev<-curr.
- Handle n == 0 and n == 1 separately before splitting, otherwise the slices become empty/degenerate.
Part C — Delete an Interval from a Sorted Interval List
Constraints
- 0 <= number of intervals <= 10^4
- Each interval is half-open [start, end) with start < end
- Intervals are sorted by start and pairwise non-overlapping
- del_interval is [d_start, d_end) with d_start <= d_end
- Output preserves sorted, non-overlapping order
Examples
Input: ([[0,2],[3,4],[5,7]], [1,6])
Expected Output: [[0, 1], [6, 7]]
Explanation: Delete [1,6): [0,2)->[0,1) (left remainder), [3,4) fully covered (removed), [5,7)->[6,7) (right remainder).
Input: ([[0,5]], [2,3])
Expected Output: [[0, 2], [3, 5]]
Explanation: Deletion sits strictly inside [0,5), splitting it into [0,2) and [3,5).
Input: ([[0,10]], [0,10])
Expected Output: []
Explanation: Deletion exactly covers the only interval ⇒ nothing remains.
Input: ([], [1,2])
Expected Output: []
Explanation: Empty input ⇒ empty output.
Input: ([[1,3],[4,6]], [10,20])
Expected Output: [[1, 3], [4, 6]]
Explanation: Deletion is entirely to the right of all intervals ⇒ nothing changes.
Input: ([[1,5]], [0,3])
Expected Output: [[3, 5]]
Explanation: Deletion covers the left part; only the right remainder [3,5) survives.
Input: ([[1,5]], [3,10])
Expected Output: [[1, 3]]
Explanation: Deletion covers the right part; only the left remainder [1,3) survives.
Input: ([[0,2],[4,6]], [2,4])
Expected Output: [[0, 2], [4, 6]]
Explanation: Half-open endpoints: [0,2) ends exactly where deletion starts and [4,6) starts exactly where deletion ends ⇒ no overlap, both kept whole.
Hints
- Because intervals are half-open, an interval [start, end) does NOT overlap the deletion [ds, de) when end <= ds or start >= de — keep those unchanged. The touching endpoints (end == ds or start == de) are safe to keep whole.
- When there IS overlap, emit up to two surviving pieces: the left remainder [start, ds) if start < ds, and the right remainder [de, end) if end > de. A deletion strictly inside one interval emits both pieces (a split).
- Single pass, no sorting needed since the input is already sorted; the output stays sorted automatically.