Skip to content

Latest commit

 

History

History

1673.Find the Most Competitive Subsequence

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

English Version

题目描述

给你一个整数数组 nums 和一个正整数 k ,返回长度为 k 且最具 竞争力 nums 子序列。

数组的子序列是从数组中删除一些元素(可能不删除元素)得到的序列。

在子序列 a 和子序列 b 第一个不相同的位置上,如果 a 中的数字小于 b 中对应的数字,那么我们称子序列 a 比子序列 b(相同长度下)更具 竞争力 。 例如,[1,3,4][1,3,5] 更具竞争力,在第一个不相同的位置,也就是最后一个位置上, 4 小于 5

 

示例 1:

输入:nums = [3,5,2,6], k = 2
输出:[2,6]
解释:在所有可能的子序列集合 {[3,5], [3,2], [3,6], [5,2], [5,6], [2,6]} 中,[2,6] 最具竞争力。

示例 2:

输入:nums = [2,4,3,3,5,4,9,6], k = 4
输出:[2,3,3,4]

 

提示:

  • 1 <= nums.length <= 105
  • 0 <= nums[i] <= 109
  • 1 <= k <= nums.length

解法

方法一:栈

我们从左到右遍历数组 nums,维护一个栈 stk,遍历过程中,如果当前元素 nums[i] 小于栈顶元素,且栈中元素个数加上 $n-i$ 大于 $k$,则将栈顶元素出栈,直到不满足上述条件为止。此时如果栈中元素个数小于 $k$,则将当前元素入栈。

遍历结束后,栈中元素即为所求。

时间复杂度 $O(n)$,空间复杂度 $O(k)$。其中 $n$ 为数组 nums 的长度。

Python3

class Solution:
    def mostCompetitive(self, nums: List[int], k: int) -> List[int]:
        stk = []
        n = len(nums)
        for i, v in enumerate(nums):
            while stk and stk[-1] > v and len(stk) + n - i > k:
                stk.pop()
            if len(stk) < k:
                stk.append(v)
        return stk

Java

class Solution {
    public int[] mostCompetitive(int[] nums, int k) {
        Deque<Integer> stk = new ArrayDeque<>();
        int n = nums.length;
        for (int i = 0; i < nums.length; ++i) {
            while (!stk.isEmpty() && stk.peek() > nums[i] && stk.size() + n - i > k) {
                stk.pop();
            }
            if (stk.size() < k) {
                stk.push(nums[i]);
            }
        }
        int[] ans = new int[stk.size()];
        for (int i = ans.length - 1; i >= 0; --i) {
            ans[i] = stk.pop();
        }
        return ans;
    }
}

C++

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

Go

func mostCompetitive(nums []int, k int) []int {
	stk := []int{}
	n := len(nums)
	for i, v := range nums {
		for len(stk) > 0 && stk[len(stk)-1] > v && len(stk)+n-i > k {
			stk = stk[:len(stk)-1]
		}
		if len(stk) < k {
			stk = append(stk, v)
		}
	}
	return stk
}

...