Solve Dependency, Prefix, and Cache Problems
Company: eBay
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Onsite
Quick Answer: This set of problems evaluates graph algorithms for dependency and cycle detection, efficient data structure design for prefix-based word storage, and cache eviction policy implementation, assessing skills in algorithmic analysis, data structures, and time/space complexity within the Coding & Algorithms domain.
Part 1: Determine Whether All Tasks Can Be Completed
Constraints
- 0 <= numTasks <= 100000
- 0 <= len(prerequisites) <= 200000
- Each prerequisite is a pair [a, b] with 0 <= a, b < numTasks
Examples
Input: (2, [[1, 0]])
Expected Output: True
Explanation: Task 0 can be done first, then task 1. There is no cycle.
Input: (2, [[1, 0], [0, 1]])
Expected Output: False
Explanation: Task 0 depends on task 1 and task 1 depends on task 0, forming a cycle.
Hints
- Model the tasks as a directed graph and look for a way to detect cycles.
- If you repeatedly remove tasks with indegree 0 and cannot process all tasks, a cycle must exist.
Part 2: Implement a Prefix-Based Word Store
Constraints
- 0 <= len(operations) <= 20000
- Each word or prefix has length between 1 and 2000
- The sum of lengths of all words and prefixes is at most 200000
- All characters are lowercase English letters a through z
Examples
Input: [('insert', 'apple'), ('search', 'apple'), ('search', 'app'), ('startsWith', 'app'), ('insert', 'app'), ('search', 'app')]
Expected Output: [None, True, False, True, None, True]
Explanation: 'apple' is inserted first. Exact search for 'apple' is True, exact search for 'app' is False until 'app' is inserted, while startsWith('app') is already True because 'apple' starts with it.
Input: [('search', 'dog'), ('startsWith', 'do')]
Expected Output: [False, False]
Explanation: No words have been inserted yet, so both the exact search and prefix check return False.
Hints
- A trie stores one character per level and is a natural fit for both exact word checks and prefix checks.
- Exact search and prefix search traverse similarly; only exact search must verify an end-of-word marker.
Part 3: Implement a Fixed-Capacity Least-Recently-Used Cache
Constraints
- 1 <= capacity <= 30000
- 0 <= len(operations) <= 200000
- 0 <= key <= 1000000000
- 0 <= value <= 1000000000
Examples
Input: (2, [('put', 1, 1), ('put', 2, 2), ('get', 1), ('put', 3, 3), ('get', 2), ('put', 4, 4), ('get', 1), ('get', 3), ('get', 4)])
Expected Output: [None, None, 1, None, -1, None, -1, 3, 4]
Explanation: After getting key 1, it becomes most recently used. Putting 3 evicts 2. Putting 4 later evicts 1.
Input: (1, [('put', 2, 1), ('put', 3, 2), ('get', 2), ('get', 3), ('put', 4, 3), ('get', 4)])
Expected Output: [None, None, -1, 2, None, 3]
Explanation: With capacity 1, each new key evicts the previous one. Key 2 is gone after putting 3, and key 3 is gone after putting 4.
Hints
- Use a hash map for O(1) access to cache entries and a doubly linked list to track recency order.
- Move a key to the front whenever it is read or updated, and remove from the tail when eviction is needed.