Question presented to candidate: "Given an array of integers, return the length of its longest strictly increasing subsequence. Start with whatever works, then make it faster, and tell me how you would return the subsequence itself. Please code it in Python."
What a strong answer should cover:
- The O(n²) DP:
dp[i]= LIS length ending at i,dp[i] = 1 + max(dp[j])over earlier smallernums[j], answer =max(dp)(notdp[-1]). - The O(n log n) idea:
tails[k]= smallest possible tail of an increasing subsequence of length k + 1;tailsstays sorted, so each number is placed with one binary search. - That
tailsis not itself an LIS, and how parent pointers rebuild a real one. - Strict vs non-decreasing:
bisect_leftvsbisect_right. - Python details: the
bisectmodule,max(dp)raisingValueErroron an empty list, and why the O(n²) double loop is slow in pure Python for n in the tens of thousands.
Clarifying questions expected:
- Strictly increasing or non-decreasing?
- Length only, or the subsequence too?
- How large can n be?
Code / implementation expected: Yes — the O(n log n) tails solution with bisect_left in Python; the O(n²) DP is a good first step to mention or write.