Solve two interview coding problems
Company: Uber
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: These two problems evaluate algorithmic problem-solving skills: the first focuses on spatial reasoning and grid-based distance computation relative to obstacles, while the second targets tree traversal and character-frequency reasoning for ancestor-path palindrome checks.
Part 1: Find valid robot locations in a grid
Constraints
- 0 <= number of rows <= 500
- 0 <= number of columns <= 500
- All rows in grid have the same length
- Each grid cell is either . or #
- target has exactly 4 integers
- 1 <= target[i] <= max(1, rows, cols)
Examples
Input: (['#####', '#...#', '#.#.#', '#...#', '#####'], [2, 1, 2, 1])
Expected Output: [(1, 2), (3, 2)]
Explanation: Cells (1, 2) and (3, 2) both have obstacles 2 steps to the left and right, and 1 step up and down.
Input: (['####', '#..#', '#..#', '####'], [1, 1, 2, 2])
Expected Output: [(1, 1)]
Explanation: Only the top-left interior cell has the exact distances left=1, up=1, right=2, down=2.
Input: (['.#.', '...', '.#.'], [1, 1, 1, 1])
Expected Output: []
Explanation: Every empty cell is missing an obstacle in at least one direction before the boundary.
Input: ([], [1, 1, 1, 1])
Expected Output: []
Explanation: An empty grid has no valid robot positions.
Input: (['.'], [1, 1, 1, 1])
Expected Output: []
Explanation: A single empty cell has no obstacle in any direction, so it cannot match.
Hints
- For every empty cell, you need the nearest obstacle in four directions. Try sweeping left-to-right, right-to-left, top-to-bottom, and bottom-to-top to precompute these distances.
- A cell cannot match if any one of the four directions has no obstacle before the boundary.
Part 2: Count ancestor path segments that can form a palindrome
Constraints
- 1 <= treeNodes <= 200000
- len(nodes) == treeNodes
- len(nodeFrom) == len(nodeTo) == treeNodes - 1
- 0 <= len(queries) <= 200000
- nodes[i] is a lowercase English letter
- 0 <= queries[i] < treeNodes
- The given edges form a tree rooted at node 0
Examples
Input: (4, ['z', 'a', 'a', 'a'], [0, 0, 1], [1, 2, 3], [3])
Expected Output: [3]
Explanation: The path segments from node 3 are a, aa, and aaz. All three can be rearranged into palindromes.
Input: (5, ['a', 'b', 'a', 'c', 'b'], [0, 1, 1, 0], [1, 2, 3, 4], [2, 3, 4, 0])
Expected Output: [2, 1, 1, 1]
Explanation: For node 2, segments a and aba are valid. For node 3 only c is valid. For node 4 only b is valid. The root contributes one valid segment by itself.
Input: (4, ['a', 'a', 'b', 'b'], [0, 1, 2], [1, 2, 3], [3, 2])
Expected Output: [4, 2]
Explanation: For node 3, all four upward segments are valid. For node 2, only b and baa are valid.
Input: (1, ['x'], [], [], [0])
Expected Output: [1]
Explanation: A single node always forms one valid segment consisting of itself.
Input: (2, ['a', 'b'], [0], [1], [1, 1, 0])
Expected Output: [1, 1, 1]
Explanation: Repeated queries should produce repeated answers. Node 1 has only one valid upward segment, and node 0 also has one.
Hints
- A path can be rearranged into a palindrome if its character-parity mask has at most one bit set. Think in terms of xor masks instead of full frequency tables.
- During a DFS, maintain counts of prefix masks seen on the current root-to-parent path. For a node q, you only need masks equal to prefix[q] or differing from it by exactly one bit.