1673. Find the Most Competitive Subsequence

题目:

Given an integer array nums and a positive integer k, return the most competitive subsequence of nums of size k.

An array's subsequence is a resulting sequence obtained by erasing some (possibly zero) elements from the array.

We define that a subsequence a is more competitive than a subsequence b (of the same length) if in the first position where a and b differ, subsequence a has a number less than the corresponding number in b. For example, [1,3,4] is more competitive than [1,3,5] because the first position they differ is at the final number, and 4 is less than 5.

Example 1:

Input: nums = [3,5,2,6], k = 2
Output: [2,6]
Explanation: Among the set of every possible subsequence: {[3,5], [3,2], [3,6], [5,2], [5,6], [2,6]}, [2,6] is the most competitive.

Example 2:

Input: nums = [2,4,3,3,5,4,9,6], k = 4
Output: [2,3,3,4]

Constraints:

  • 1 <= nums.length <= 10^5
  • 0 <= nums[i] <= 10^9
  • 1 <= k <= nums.length

思路:

观察题目我们可以发现,要求返回的数组是在permutation的情况下越小越好,但是又要保证返回的数组长度要等于给定值k。这里其实使用的是单调栈,不过因为返回的是个vector,我们可以直接用vector来代替stack。遍历数组,对于数组中的每个数,无非是两种情况:pop或者push。为了保持单调栈我们需要用while循环进行持续pop,因为可能出现比如1,1,5,6,3这种情况,比如栈内是[1,1,5,6],这时遇到3,我们就需要pop掉5和6再把三压入栈,最后栈内为[1,1,3]。综上所述,while的条件是栈不为空,并且栈顶要大于当前数组中的数字,这两个条件维护了单调栈。同时因为我们需要返回给定长度为k的数组,因此要在pop的同时,数组剩下的元素加上我栈内元素足够制造k长度的数组去返回:数组总长度 - 当前已经遍历的所有数的个数 + 栈内数字个数 需要大于等于k。这里其实也很好理解,前两部分减完其实就是数组内剩下的数的个数,然后它与栈内个数相加要大于等于k即可。在pop完之后,如果发现当前栈的个数不够k,将当前数组中的数压入栈即可。

代码:

class Solution {
public:
    vector<int> mostCompetitive(vector<int>& nums, int k) {
        vector<int> res;
        for(int i=0;i<nums.size();i++)
        {
            while(res.size()&&res.back()>nums[i]&&i+1+k-res.size()<=nums.size())
                res.pop_back();
            if(res.size()<k)
                res.push_back(nums[i]);
        }
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_49991368/article/details/112972621