leetcode 2386. 找出数组的第 K 大和【小根堆】

原题链接:2386. 找出数组的第 K 大和

题目描述:

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

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

返回数组的 第 k 大和 。

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

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

输入输出描述:

示例 1:

输入:nums = [2,4,-2], k = 5
输出:2
解释:所有可能获得的子序列和列出如下,按递减顺序排列:
- 6、4、4、2、2、0、0、-2
数组的第 5 大和是 2 。

示例 2:

输入:nums = [1,-2,3,4,-10,12], k = 16
输出:10
解释:数组的第 16 大和是 10 。

提示:

  • n == nums.length
  • 1 <= n <= 10^5
  • -10^9 <= nums[i] <= 10^9
  • 1 <= k <= min(2000, 2^n)

解题思路:

假设我们此时有一个数组[-1,-2,0,1,2,3],此时我们的最大子序列和为0+1+2+3=6,我们需要求得是第k大子序列和,我们需要将当前最大子序列和变小,要变小就是要减去某些正数或者加上某些负数,我们将所有的负数都取绝对值,那么此时的操作就变为了减去某些数。我们还需要知道的一点就是最大的子序列和减去最小的子序列和得到的就是最大的子序列和,最大的子序列和减去第二小的子序列和得到的就是第二大的子序列和,依此类推,最大的子序列和减去第k小的子序列和就是第k大的子序列和,所以就将原问题转换为了求第k小的子序列和,那么我们可以进行如下操作求出第k小的子序列和,需要先把序列中所有的负数变为正数:

当前序列为[2,1,3],从小到大排序之后变为[1,2,3]。

最开始是一个空序列[]

然后考虑元素1,可以插入原来序列的末尾,变为[1]

然后考虑元素2,可以考虑插入[1]的末尾变为[1,2],或者替换[1]的末尾元素1变为[2]

然后考虑元素3,可以插入[1,2]的末尾变为[1,2,3],或者替换[1,2]的末尾元素2变为[1,3]

或者将[2]的末尾元素2替换为3变为[3],或者插入[2]的末尾变为[2,3]

对于上述过程使用小根堆进行维护,可以从小到大生成第k小的子序列,然后我们的初始序列所有非负整数的和就是最大子序列和,然后最大子序列和减去第k小子序列和就是答案。

时间复杂度:O(nlog(n)+klog(k)),n表示nums的长度。

空间复杂度:O(k)。

cpp代码如下:

class Solution {
    typedef long long LL;
    typedef pair<LL,int>PLI;
public:
    long long kSum(vector<int>& nums, int k) {
        LL sum=0;
        int n=nums.size();
        for(int i=0;i<n;i++){
            if(nums[i]>=0){
                sum+=nums[i];
            }else {
                nums[i]=-nums[i];
            }
        }
        sort(nums.begin(),nums.end());
        priority_queue<PLI,vector<PLI>,greater<PLI>>pq;
        pq.push({0,0});
        while(--k){
            auto [s,i]=pq.top();
            pq.pop();
            if(i<n){
                pq.push({s+nums[i],i+1});
                if(i){
                    pq.push({s+nums[i]-nums[i-1],i+1});
                }
            }
        }
        return sum-pq.top().first;
    }
};

相关推荐

  1. leetcode 2386. K

    2024-03-12 23:50:05       44 阅读
  2. LeetCode2386. K

    2024-03-12 23:50:05       44 阅读
  3. LeetCode每日一题[C++]-K

    2024-03-12 23:50:05       42 阅读
  4. 2024.3.9力扣每日一题—— K

    2024-03-12 23:50:05       34 阅读
  5. leetcode 2834.美丽

    2024-03-12 23:50:05       34 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-12 23:50:05       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-12 23:50:05       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-12 23:50:05       82 阅读
  4. Python语言-面向对象

    2024-03-12 23:50:05       91 阅读

热门阅读

  1. DDR3 NATIVE接口

    2024-03-12 23:50:05       37 阅读
  2. 【PTA】L1-021 L1-022 L1-023 L1-024 L1-025(C)第四天

    2024-03-12 23:50:05       42 阅读
  3. 【面试准备日常】从头复习mysql--20240308

    2024-03-12 23:50:05       38 阅读
  4. MongoDB聚合运算符:$divide

    2024-03-12 23:50:05       43 阅读
  5. [go 面试] 分布式事务框架选择与实践

    2024-03-12 23:50:05       43 阅读
  6. 软考笔记--基于架构的软件开发方法

    2024-03-12 23:50:05       49 阅读
  7. k8s(kubernetes)怎么查看pod服务对应哪些docker容器

    2024-03-12 23:50:05       44 阅读
  8. MongoDB聚合运算符:$dateTrunc

    2024-03-12 23:50:05       45 阅读
  9. CMS垃圾收集

    2024-03-12 23:50:05       47 阅读
  10. python入门(一)

    2024-03-12 23:50:05       38 阅读
  11. IOS面试题object-c 21-30

    2024-03-12 23:50:05       45 阅读
  12. R语言中ggplot2图例位置、颜色、背景、标题

    2024-03-12 23:50:05       45 阅读