Solve Four Interview Coding Problems
Company: Pinterest
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Onsite
Quick Answer: This question set evaluates algorithmic problem-solving skills including graph traversal and itinerary reconstruction, time-sorted search and binary search, grid-based simulation of ray traversal, and data structure design for efficient updates and leaderboard generation.
Part 1: Reconstruct Itinerary from Airline Tickets
Constraints
- 0 <= len(tickets) <= 10^4
- Each ticket is a pair [from, to] of non-empty strings
- Duplicate tickets may exist
- Assume at least one valid itinerary exists for the given start, except the empty-ticket case
Examples
Input: ([['MUC', 'LHR'], ['JFK', 'MUC'], ['SFO', 'SJC'], ['LHR', 'SFO']], 'JFK')
Expected Output: ['JFK', 'MUC', 'LHR', 'SFO', 'SJC']
Explanation: There is only one valid way to use all tickets starting from JFK.
Input: ([['JFK', 'SFO'], ['JFK', 'ATL'], ['SFO', 'ATL'], ['ATL', 'JFK'], ['ATL', 'SFO']], 'JFK')
Expected Output: ['JFK', 'ATL', 'JFK', 'SFO', 'ATL', 'SFO']
Explanation: Multiple itineraries exist, so the lexicographically smallest valid one must be chosen.
Input: ([], 'JFK')
Expected Output: ['JFK']
Explanation: Edge case: with no tickets, the itinerary is just the starting airport.
Input: ([['JFK', 'A'], ['JFK', 'A'], ['A', 'JFK']], 'JFK')
Expected Output: ['JFK', 'A', 'JFK', 'A']
Explanation: Duplicate tickets must still be treated as separate edges and used exactly once.
Hints
- Using every ticket exactly once is a strong hint toward an Eulerian path/trail approach.
- If you sort destinations in reverse order, you can pop the smallest next destination efficiently from the end.
Part 2: Sort Timestamped Logs and Find Target Position
Constraints
- 0 <= len(logs) <= 10^5
- Each log is [timestamp, message]
- Timestamps are valid zero-padded strings in the format YYYY-MM-DD HH:MM:SS
- If multiple logs share the same timestamp, return the leftmost matching index after sorting
Examples
Input: ([['2024-03-01 09:00:00', 'A'], ['2024-02-28 12:00:00', 'B'], ['2024-03-01 08:00:00', 'C']], '2024-03-01 08:00:00')
Expected Output: ([['2024-02-28 12:00:00', 'B'], ['2024-03-01 08:00:00', 'C'], ['2024-03-01 09:00:00', 'A']], 1)
Explanation: After sorting, the target timestamp appears at index 1.
Input: ([['2024-03-01 09:00:00', 'A'], ['2024-02-28 12:00:00', 'B'], ['2024-03-01 08:00:00', 'C']], '2024-03-01 08:30:00')
Expected Output: ([['2024-02-28 12:00:00', 'B'], ['2024-03-01 08:00:00', 'C'], ['2024-03-01 09:00:00', 'A']], 2)
Explanation: The target is missing, so return the insertion position between 08:00 and 09:00.
Input: ([['2024-01-01 00:00:00', 'x'], ['2024-01-01 00:00:00', 'y'], ['2023-12-31 23:59:59', 'z']], '2024-01-01 00:00:00')
Expected Output: ([['2023-12-31 23:59:59', 'z'], ['2024-01-01 00:00:00', 'x'], ['2024-01-01 00:00:00', 'y']], 1)
Explanation: For duplicate timestamps, return the leftmost matching index.
Input: ([], '2024-01-01 00:00:00')
Expected Output: ([], 0)
Explanation: Edge case: an empty log list has insertion index 0.
Hints
- Because the timestamps are zero-padded, you do not need to parse them into datetime objects to compare them correctly.
- Use a lower-bound style binary search: find the first position whose timestamp is not less than the target.
Part 3: Simulate a Lighthouse Light Ray in a Grid
Constraints
- 1 <= number of rows, number of columns <= 200
- All rows have the same length
- Grid cells contain only '.', '#', '/', or backslash
- The start position is inside the grid and is not a blocker
Examples
Input: (['...', '...'], (0, 0), 'R')
Expected Output: ([(0, 0), (0, 1), (0, 2)], 'EXIT', (0, 3), 'R')
Explanation: The ray moves straight across the first row and exits the grid.
Input: (['..#', '...'], (0, 0), 'R')
Expected Output: ([(0, 0), (0, 1)], 'BLOCKED', (0, 2), 'R')
Explanation: The blocker is not included in the illuminated path.
Input: (['.\\.', '...', '...'], (0, 0), 'R')
Expected Output: ([(0, 0), (0, 1), (1, 1), (2, 1)], 'EXIT', (3, 1), 'D')
Explanation: The backslash mirror turns the ray downward.
Input: (['/\\', '\\/'], (0, 0), 'U')
Expected Output: ([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)], 'LOOP', (0, 0), 'U')
Explanation: The mirrors create a cycle that returns to the same cell with the same direction.
Input: (['.'], (0, 0), 'L')
Expected Output: ([(0, 0)], 'EXIT', (0, -1), 'L')
Explanation: Edge case: a single-cell grid exits immediately after the start cell.
Hints
- Track full states as (row, col, direction); revisiting the same cell with a different direction is not the same state.
- Apply the mirror effect of the current cell before moving to the next cell.
Part 4: Escape-Room Leaderboard Data Structure
Constraints
- 1 <= num_rooms <= 10^5
- 0 <= len(operations) <= 2 * 10^5
- A player enters at most once; duplicate enters may be ignored
- Advancing a player already in the last room is a no-op
- Querying a missing player with 'where' should return -1
Examples
Input: (4, [('enter', 'alice'), ('enter', 'bob'), ('advance', 'alice'), ('where', 'alice'), ('leaderboard', 2)])
Expected Output: [1, ['alice', 'bob']]
Explanation: Alice is farther ahead, so she leads the leaderboard.
Input: (5, [('enter', 'bob'), ('enter', 'alice'), ('advance', 'alice'), ('advance', 'bob'), ('leaderboard', 2)])
Expected Output: [['alice', 'bob']]
Explanation: Both players are in room 1, but Alice entered room 1 earlier, so she comes first.
Input: (3, [('enter', 'a'), ('enter', 'b'), ('enter', 'c'), ('advance', 'a'), ('advance', 'a'), ('advance', 'b'), ('leaderboard', 5), ('where', 'c')])
Expected Output: [['a', 'b', 'c'], 0]
Explanation: The leaderboard is ordered by room 2, then room 1, then room 0.
Input: (2, [('leaderboard', 3), ('where', 'ghost')])
Expected Output: [[], -1]
Explanation: Edge case: no players have entered yet.
Input: (1, [('enter', 'solo'), ('advance', 'solo'), ('where', 'solo'), ('leaderboard', 1)])
Expected Output: [0, ['solo']]
Explanation: With only one room, advancing changes nothing.
Hints
- Keep players bucketed by room, and preserve arrival order inside each room.
- A hash map from player ID to its current node/room lets you remove and reinsert a player in O(1) when they advance.