Solve Grid Path and Graph Sampling
Company: Databricks
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: This question evaluates graph algorithms and probabilistic/combinatorial reasoning, covering multi-criteria shortest-path optimization (minimizing travel time with a secondary fee objective) and uniform random sampling of edge sets that connect disjoint components.
Part 1: Shortest-Time Grid Path with Minimum Fee
Constraints
- 1 <= number of rows, number of columns <= 200
- grid contains exactly one 'S' and exactly one 'E'
- fees[r][c] is a non-negative integer
- You may move only in 4 directions: up, down, left, right
- Blocked cells are marked with '#'; their fee values, if present, are ignored
Examples
Input: (["S..", "..E"], [[0, 5, 1], [1, 1, 2]])
Expected Output: (3, 4)
Explanation: All shortest paths take 3 moves. The cheapest such path is down, right, right with total fee 1 + 1 + 2 = 4.
Input: (["S.E", "..."], [[0, 100, 1], [1, 1, 1]])
Expected Output: (2, 101)
Explanation: The direct top-row path is shortest with time 2, even though a longer route has a smaller fee. Time has higher priority than fee.
Input: (["S#E"], [[0, 0, 0]])
Expected Output: None
Explanation: The blocked cell prevents any path from S to E.
Input: (["SE"], [[0, 7]])
Expected Output: (1, 7)
Explanation: Edge case: the end is adjacent to the start, so only one move is needed.
Hints
- Treat the path score as a pair: first minimize time, then minimize fee.
- A priority queue works well because every move adds a non-negative pair (1, fee_of_next_cell).
Part 2: Uniformly Sample Connecting Cross-Graph Edges
Constraints
- 1 <= number of components <= 100000
- Each component is non-empty
- All vertex labels are distinct integers
- The total number of vertices across all components is <= 200000
- Do not enumerate all valid connecting edge sets; their number can be enormous
Examples
Input: ([[5, 8]], 42)
Expected Output: []
Explanation: Edge case: there is only one component, so the graph is already connected.
Input: ([[1, 2], [10, 11, 12]], 1)
Expected Output: [(1, 12)]
Explanation: With two components, there is only one component-level tree edge. The seed determines which actual vertex pair is chosen.
Input: ([[1], [2, 3], [4]], 2)
Expected Output: [(1, 4), (2, 4)]
Explanation: The weighted Prüfer sequence selects component 2, creating component edges (0, 2) and (1, 2). The seed then picks the concrete vertices.
Input: ([[1, 2], [3], [4, 5], [6]], 3)
Expected Output: [(2, 3), (2, 6), (3, 4)]
Explanation: The sampled component tree has three cross-component links, and the seed fixes the chosen endpoints inside those components.
Hints
- If you compress each connected component into one super-node, any valid answer with exactly n - 1 added edges corresponds to a tree on those super-nodes.
- For a fixed component tree, count how many concrete vertex-edge choices it expands to. Prüfer sequences can sample trees with degree-dependent weights.