长度为K的最大子序列

给你一个整数数组 nums 和一个整数 k 。你需要找到 nums 中长度为 k 的 子序列 ,且这个子序列的 和最大 。
请你返回 任意 一个长度为 k 的整数子序列。
子序列 定义为从一个数组里删除一些元素后,不改变剩下元素的顺序得到的数组。

  1. 剔除掉 num.length - k 个 最小的 元素,剩下的元素,就是要求解的:k个最大的子序列。这可以用优先级队列(小顶堆)来实现。
  2. 要保证 k 个最大元素的顺序不能乱。
  3. 优先级队列 poll 方法移除: num.length - k 个 最小的元素的 下标,并将之转存到:HashSet
  4. 遍历 nums 数组,若 下标在:HashSet 中,则不处理;否则该元素就是:最大子序列中的 一个元素。

题目:https://leetcode.cn/problems/find-subsequence-of-length-k-with-the-largest-sum/description/

class Solution {
    public int[] maxSubsequence(int[] nums, int k) {
        if(nums.length == k){
            return nums;
        }

        //小顶堆,保存 nums 数组的下标。堆顶元素就是:nums 数组中最小的那个元素的 index
        PriorityQueue<Integer> pq = new PriorityQueue<>((o1, o2) -> Integer.compare(nums[o1], nums[o2]));

        for (int i = 0; i < nums.length ; i++) {
            pq.offer(i);
        }

        //存储 nums.length-k 个元素的下标,这些元素是:元素值比较小的那些元素
        Set<Integer> minSet = new HashSet<>();
        int count = 0;
        while (count < nums.length - k) {
            minSet.add(pq.poll());
            count++;
        }
        
        int[] result = new int[k];
        int index = 0;
        for (int i = 0; i < nums.length; i++) {
            if (minSet.contains(i)) {
                //该元素是较小的元素,不做处理
                continue;
            }
            //否则该元素就是:最大子序列中的 一个元素。
            result[index++] = nums[i];
        }
        return result;
    }
}

参考:最大子序列和问题

posted @ 2023-08-06 19:47  大熊猫同学  阅读(72)  评论(0编辑  收藏  举报