码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 求数组第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+1​−ai​,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​),ai​≥0。

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

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

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

    代码

    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小。

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

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

    然后转弱化版解法。

    代码略。


  • 相关阅读:
    数学建模| 优化入门+多目标规划
    IBM Spectrum LSF Application Center 以应用程序为中心的工作负载提交和管理
    PMP备考大全:经典题库(敏捷管理第1期)
    提高业主好评度和满意度?快鲸物业管理系统至关重要!
    跨境电商:为民营经济注入新活力
    Mysql索引详解(图文并茂)
    嵌入式开发:技巧和窍门——提高嵌入式软件代码质量的7个技巧
    CS109: Probability for Computer Scientists, Summer 2022笔记合集
    JavaWeb-JavaScript
    ADS基础教程22 - 有限元电磁仿真(FEM)
  • 原文地址:https://blog.csdn.net/weixin_45750972/article/details/126453547
  • 最新文章
  • 【JVM】编译执行与解释执行的区别是什么?JVM 使用哪种方式?
    用 Hashids 优雅解决 C 端自增 ID 暴露问题
    V8引擎 精品漫游指南--Ignition篇(上) 指令 栈帧 槽位 调用约定 内存布局 基础内容
    LLVM Pass快速入门(四):代码插桩
    milkup:桌面端 markdown AI续写和即时渲染
    基于项目工程构建SBOM(软件物料清单)的研究
    鸿蒙应用开发UI基础第二节:鸿蒙应用程序框架核心解析与实操
    .NET 中如何快速实现 List 集合去重?
    扣子Coze实战:从0到1打造抖音+小红书热点监控智能体
    浅谈数据访问层
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号