Solve binary-search knapsack & graph shortest path
Company: Microsoft
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: Medium
Interview Round: Take-home Project
Quick Answer: This question evaluates a candidate's ability to apply algorithmic optimization by using binary search instead of dynamic programming for a knapsack-style selection problem and to construct and compute shortest paths on a weighted graph from custom input.
Maximum Items Within Capacity (Binary Search on Prefix Sums)
Constraints
- 0 <= len(weights) <= 10^5
- weights is sorted in non-decreasing order
- 1 <= weights[i] <= 10^9
- 0 <= capacity <= 10^14
Examples
Input: ([1, 2, 3, 4, 5], 10)
Expected Output: 4
Explanation: Prefix sums [0,1,3,6,10,15]; largest <= 10 is 10 (4 items: 1+2+3+4).
Input: ([1, 2, 3, 4, 5], 15)
Expected Output: 5
Explanation: All five items sum to 15, exactly the capacity.
Input: ([2, 3, 5, 7], 1)
Expected Output: 0
Explanation: Even the cheapest item (weight 2) exceeds capacity 1.
Input: ([], 100)
Expected Output: 0
Explanation: No items available, so 0 can be taken.
Input: ([5], 5)
Expected Output: 1
Explanation: Single item of weight 5 fits exactly in capacity 5.
Input: ([1, 1, 1, 1], 0)
Expected Output: 0
Explanation: Zero capacity admits no items.
Input: ([3, 3, 3], 8)
Expected Output: 2
Explanation: Prefix sums [0,3,6,9]; largest <= 8 is 6, so 2 items.
Hints
- Build a prefix-sum array P where P[i] is the total weight of the first i items. P[0] = 0.
- Because weights are non-negative, P is non-decreasing, so it is sorted — a prerequisite for binary search.
- Find the largest index i such that P[i] <= capacity. That index i is your answer (number of items taken). bisect_right(P, capacity) - 1 gives it directly.
Shortest Path in a Weighted Graph (Dijkstra)
Constraints
- 1 <= n <= 10^4
- 0 <= len(edges) <= 10^5
- 0 <= u, v < n
- 0 <= w <= 10^6 (non-negative weights, so Dijkstra applies)
- 0 <= source, target < n
Examples
Input: (5, [[0, 1, 4], [0, 2, 1], [2, 1, 2], [1, 3, 1], [2, 3, 5]], 0, 3)
Expected Output: 4
Explanation: Path 0->2->1->3 with weight 1+2+1 = 4 beats 0->2->3 (1+5=6) and 0->1->3 (4+1=5).
Input: (4, [[0, 1, 1], [1, 2, 1], [2, 3, 1]], 0, 3)
Expected Output: 3
Explanation: Only path is 0->1->2->3, total 3.
Input: (4, [[0, 1, 5]], 0, 3)
Expected Output: -1
Explanation: Node 3 is isolated and unreachable from 0.
Input: (1, [], 0, 0)
Expected Output: 0
Explanation: Source equals target with no edges; distance is 0.
Input: (3, [[0, 1, 10], [1, 2, 10], [0, 2, 100]], 0, 2)
Expected Output: 20
Explanation: Two-hop path 0->1->2 (20) beats the direct edge 0->2 (100).
Input: (6, [[0, 1, 7], [0, 2, 9], [0, 5, 14], [1, 2, 10], [1, 3, 15], [2, 3, 11], [2, 5, 2], [3, 4, 6], [4, 5, 9]], 0, 4)
Expected Output: 20
Explanation: Classic Dijkstra example: 0->2->5->4 = 9+2+9 = 20 is the shortest route to node 4.
Hints
- Convert the edge list into an adjacency list. Because the graph is undirected, add each edge in both directions.
- Use a min-heap (priority queue) keyed by current best distance. Pop the closest unsettled node, then relax its neighbors.
- Skip stale heap entries: when you pop (d, node), if d is greater than the recorded dist[node], ignore it. Return dist[target], or -1 if it stayed infinite.