Problem Statement in English
You’re given an integer array nums and an integer k.
You need to return the most competitive subsequence of nums of size k.
A competitive subsequence is one that has the smallest lexicographical order.
Approach
You need to use a monotonic stack to solve this problem.
The metric we use popping from the stack is:
- If the stack is full and the current number is greater than the last number in the stack, we skip it.
- If the stack is not full and the current number is less than the last number in the stack, AND we have enough numbers in
numsto still reachkelements in the stack, OR, there are already $k$ elements in the stack, we pop from the stack.
This is because we must have $k$ elements in the stack at the end.
Solution in Python
class Solution:
def mostCompetitive(self, nums: List[int], k: int) -> List[int]:
stack = []
l = len(nums)
for i, num in enumerate(nums):
if len(stack) == k and num >= stack[-1]:
continue
while stack and stack[-1] > num and ((len(stack) < k and l-(i+1) >= k-len(stack)) or (len(stack) == k)):
stack.pop()
stack.append(num)
return stack
Complexity
Time: $O(n)$
Since we are iterating through the array once and popping from the stack at most $n$ times.Space: $O(n)$
Since we are using a stack to store the elements.
And we are done.