【LeetCode】2386. 找出数组的第 K 大和

本文介绍了一种算法,通过首先计算数组的最大值,然后对数组取绝对值排序,再利用最小堆(PriorityQueue)进行全排列来找到数组的第k大子序列和。在Java代码中,作者使用了自定义Comparator实现大顶堆功能。
摘要由CSDN通过智能技术生成

给你一个整数数组 nums 和一个 正 整数 k 。你可以选择数组的任一 子序列 并且对其全部元素求和。

数组的 第 k 大和 定义为:可以获得的第 k 个 最大 子序列和(子序列和允许出现重复)

返回数组的 第 k 大和 。

子序列是一个可以由其他数组删除某些或不删除元素排生而来的数组,且派生过程不改变剩余元素的顺序。

注意:空子序列的和视作 0 。


class Solution {
    /**
    思路很厉害,先求最大值,然后对数组取绝对值进行排序,对新数组利用最小堆进行全排列
     */
    public long kSum(int[] nums, int k) {
        long sum = 0;
        int n = nums.length;
        for(int i=0; i<n; i++) {
            if(nums[i]>=0) {
                sum += nums[i];
            } else {
                nums[i] = -nums[i];
            }
        }
        Arrays.sort(nums);
        PriorityQueue<Pair<Long, Integer>> pq = new PriorityQueue<>((a,b)->Long.compare(a.getKey(),b.getKey()));
        pq.offer(new Pair<>(0L,0));
        while(--k>0) {
            Pair<Long,Integer> pair = pq.poll();
            Long s = pair.getKey();
            int i = pair.getValue();
            if(i<n) {
                pq.offer(new Pair<>(s+nums[i],i+1));
                if(i>0) {
                    pq.offer(new Pair<>(s-nums[i-1]+nums[i], i+1));
                }
            }
        }

        return sum-pq.peek().getKey();
    }
}

补充:PriorityQueue的用法

不指定Comparator时默认为最小堆,通过传入自定义的Comparator函数可以实现大顶堆。使用offer添加元素,使用poll取出元素。
最小堆:每次poll的时候,都是取最小值。

// 这个结构很常用
PriorityQueue<Pair<Long, Integer>> pq = new PriorityQueue<>((a,b)->Long.compare(a.getKey(),b.getKey()));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CRE_MO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值