• 求数组第k小/大的序列和


    求数组第 k k k小/大的序列和

    弱化版: a i a_i ai 非负,求第 k k k小。

    最小的子序列和是空集 0 0 0

    算法流程:

    使用优先队列,用二元组 ( s u m , i ) (sum,i) (sum,i) 表示当前下标 i i i结尾的子序列和 s u m sum sum

    初始加入 ( 0 , 0 ) (0,0) (0,0)

    每次取出队首。

    然后加入 ( s u m + a i + 1 , i + 1 ) , ( s u m + a i + 1 − a i , i + 1 ) (sum+a_{i+1},i+1),(sum+a_{i+1}-a_i,i+1) (sum+ai+1,i+1),(sum+ai+1ai,i+1)

    k k k次即为第 k k k小的序列和。

    时间复杂度: O ( n log ⁡ n + k log ⁡ k ) O(n\log n+k\log k) O(nlogn+klogk)

    证明

    我们需要证明这样做得到的子序列是不重复、不遗漏、按顺序。

    在这里插入图片描述


    强化版1: a i a_i ai 为整数,求第 k k k大。

    显然可以把 a i a_i ai分成两部分,负数和非负数。

    显然第 1 1 1大的和就是 s u m ( a i ) , a i ≥ 0 sum(a_i),a_i\ge 0 sum(ai),ai0

    接下来要么减去一个非负数,要么加上一个负数。

    这两种情况可以等价为减上一个非负数。然后我们对这些非负数从小到大排序。

    然后就转化弱化版的题目的做法,使用优先队列即可。

    代码

    class Solution {
    public:
        long long kSum(vector<int> &nums, int k) {
            long sum = 0L;
            for (int &x : nums)
                if (x >= 0) sum += x;
                else x = -x;
            sort(nums.begin(), nums.end());
            priority_queue<pair<long, int>> pq;
            pq.emplace(sum, 0);
            while (--k) {
                auto[sum, i] = pq.top();
                pq.pop();
                if (i < nums.size()) {
                    pq.emplace(sum - nums[i], i + 1); // 保留 nums[i-1]
                    if (i) pq.emplace(sum - nums[i] + nums[i - 1], i + 1); // 不保留 nums[i-1]
                }
            }
            return pq.top().first;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    强化版2: a i a_i ai 为整数,求第 k k k小。

    类似地。最小的就是负数之和。

    接下可以等价为加一个非负数,对这些非负数从小到大排序。

    然后转弱化版解法。

    代码略。


  • 相关阅读:
    postgresql|数据库|数据迁移神器ora2pg的安装部署和初步使用
    Zongmu AVM车载环视 Android SDK 简介
    四十年编程感悟
    json对象中对Long类型和String类型相互转换
    专业130+总分410+上海交通大学819信号系统与信号处理考研上交电子信息通信生医电科,真题,大纲,参考书。
    BI-SQL丨SNAPSHOT
    RestTemplate消息转换器实现详解
    基于PHP+MySQL学生信息管理系统的开发与设计
    Redis 持久化
    java 单元测试Junit
  • 原文地址:https://blog.csdn.net/weixin_45750972/article/details/126453547