二分/树上第k短路,LeetCode2386. 找出数组的第 K 大和

一、题目

1、题目描述

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

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

返回数组的 第 k 大和 。

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

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

2、接口描述

class Solution {
public:long long kSum(vector<int>& nums, int k) {}
};

3、原题链接

2386. 找出数组的第 K 大和 - 力扣(LeetCode)


二、解题报告

1、思路分析

首先明确最大子序列和就是所有正数之和sum

那么第2大就是sum加上一个非负数或者从正数中拿掉一个

那么我们可以将原数组全部取绝对值,然后求取绝对值后的第k - 1小序列和s

那么答案就是sum - s

F1 二分+枚举子集

给定mid,如何判断是否至少有k个子序列和不大于mid

对于每个nums[i]都有选或不选两种情况,那么我们递归枚举子序列

正常而言,枚举所有子序列是2^n,但是我们没必要全部枚举

我们可以将nums按升序排序

如果枚举到i,上一个子序列和为s,那么如果s + nums[i] > mid,我们就剪枝

否则cnt++,然后继续向下枚举

我们发现递归次数和cnt+1的次数有关,而cnt最多加k次,所以我们可以O(k)解决

然后定义二分边界l = 0, r = sum(nums)(nums取绝对值且排序后)

不断二分即可

F2 转化为树上第k短路

我们考虑取绝对值且排序后nums枚举子集在树上表示如下:

每个节点代表一个子序列,显然越往下节点的权值越大

那么我们只要找到从根节点出发的第k - 1短路即可

其实就是树上dijkstra,用小根堆存储节点权值和下一个元素的下标即可

2、复杂度

F1:时间复杂度:O(nlogn+klogU),即排序和二分 空间复杂度:O(min(k,n)),即取决于递归深度

F2:时间复杂度:O(nlogn+klogk)空间复杂度:O(k)

3、代码详解

​F1
class Solution {
public:long long kSum(vector<int>& nums, int k) {long long sum = 0;for(int& x : nums) if(x >= 0) sum += x; else x = -x;sort(nums.begin(), nums.end());function<bool(long long)> check = [&](long long lim){int cnt = 1;function<void(int, long long)> dfs = [&](int i, long long s){if(cnt == k || i == nums.size() || s + nums[i] > lim) return;++cnt, dfs(i + 1, s + nums[i]), dfs(i + 1, s);};dfs(0, 0);return cnt == k;};long long l = 0, r = accumulate(nums.begin(), nums.end(), 0LL);while(l < r){long long mid = l + r >> 1;if(check(mid)) r = mid;else l = mid + 1;}return sum - r;}
};

F2

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/272193.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenAI (ChatGPT)中国免费试用地址

GitHub - click33/chatgpt---mirror-station-summary: 汇总所有 chatgpt 镜像站&#xff0c;免费、付费、多模态、国内外大模型汇总等等 持续更新中…… 个人能力有限&#xff0c;搜集到的不多&#xff0c;求大家多多贡献啊&#xff01;众人拾柴火焰高&#xff01;汇总所有 cha…

如何转行成为产品经理?

转行NPDP也是很合适的一条发展路径&#xff0c;之后从事新产品开发相关工作~ 一、什么是NPDP&#xff1f; NPDP 是产品经理国际资格认证&#xff0c;美国产品开发与管理协会&#xff08;PDMA&#xff09;发起的&#xff0c;是目前国际公认的唯一的新产品开发专业认证&#xff…

arm架构服务器使用Virtual Machine Manager安装的kylin v10虚拟机

本文中使用Virtual Machine Manager安装kylin v10的虚拟机 新建虚拟机 新建虚拟机 选择镜像&#xff0c;下一步 设置内存和CPU&#xff0c;下一步 选择或创建自定义存储&#xff08;默认存储位置的磁盘空间可能不够用&#xff09; 点击管理&#xff0c;打开选择存储卷页…

15. C++泛型与符号重载

【泛型编程】 若多组类型不同的数据需要使用相同的代码处理&#xff0c;在C语言中需要编写多组代码分别处理&#xff0c;这样做显然太过繁琐&#xff0c;C增加了虚拟类型&#xff0c;使用虚拟类型可以实现一组代码处理多种类型的数据。 虚拟类型是暂时不确定的数据类型&#…

朗伯特球腔均匀光源积分球

均匀光源积分球&#xff0c;又称照度积分球或光度球、光通球&#xff0c;是光电测试中常用的一种工具。它是一个中空的球体&#xff0c;内壁涂有一层平整的漫反射材料&#xff0c;通常由金属或陶瓷制成。积分球的主要功能是收集光并将其作为散射光源或测量光源使用。 积分球的工…

LeetCode54:螺旋矩阵

题目描述 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 解题思想 模拟 循环一圈 后 跳出循环的条件&#xff1a;左边界&#xff1e;右边界 或者 上边界 > 下边界 代码 class Solution { public:vect…

突然发现一个很炸裂的平台!

平时小孟会开发很多的项目&#xff0c;很多项目不仅开发的功能比较齐全&#xff0c;而且效果比较炸裂。 今天给大家介绍一个我常用的平台&#xff0c;因含低代码平台&#xff0c;开发相当的快。 1&#xff0c;什么是低代码 低代码包括两种&#xff0c;一种低代码&#xff0c;…

Publii和GitHub:搭建个人网站的完美组合

在数字时代&#xff0c;拥有一个个人网站已经非常普遍了&#xff0c;但是&#xff0c;很多人因为技术难题而望而却步。现在&#xff0c;有了Publii&#xff0c;这一切都将变得简单。Publii是一个静态网站生成器&#xff0c;它允许你在本地计算机上创建和管理内容&#xff0c;然…

实战|环信 Vue2 uniapp Demo重构焕新!经典再升级!

项目背景 当前环信 uni-app vue2 Demo 地址升级版本 Github 地址&#xff08;临时&#xff09; 原版本功能实现方式较混乱&#xff0c;代码逻辑晦涩难懂&#xff0c;不利于开发者参考或复用。此实战项目在确保原项目功能保留的情况下进行完全重写并新增大量功能&#xff0c;以…

JavaWeb - 3 - JavaScript(JS)

JavaScript(JS)官方参考文档&#xff1a;JavaScript 教程 JavaScript&#xff08;简称&#xff1a;JS&#xff09;是一门跨平台、面向对象的脚本语言&#xff0c;是用来控制网页行为的&#xff0c;它能使网页可交互&#xff08;脚本语言就不需要编译&#xff0c;直接通过浏览器…

简介:基于 OpenTiny 组件库的 rendereless 无渲染组件架构

在 HAE 自研阶段&#xff0c;我们实现的数据双向绑定、面向对象的 JS 库、配置式开发的注册表等特性&#xff0c;随着前端技术的高速发展现在已经失去存在的意义&#xff0c;但是在 AUI 阶段探索的新思路新架构&#xff0c;经过大量的业务落地验证&#xff0c;再次推动前端领域…

【网络层】IP多播技术的相关基本概念(湖科大慕课自学笔记)

IP多播 1&#xff1a;IP多播技术的相关基本概念 我们简单举例&#xff0c;如下图所示&#xff1a; 一共有60个主机要接受来自视频服务器的同一个节目&#xff0c;如果采用单播方式&#xff0c;则视频服务器要发送60份&#xff0c;这些视频节目通过路由器的转发&#xff0c;最…

IOS覆盖率报告info文件解读

一&#xff0c;IOS覆盖率报告的生成 在做前端精准测试的时候&#xff0c;对于iOS端&#xff0c;通常会做如下操作&#xff1a; &#xff08;1&#xff09;合并覆盖率数据 如下操作&#xff1a; xcrun llvm-profdata merge coverage_file1657885040728.profraw coverage_fil…

C语言第三十七弹---文件操作(下)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 文件操作 1、文件的随机读写 1.1、fseek 1.2、ftell 1.3、rewind 2、文件读取结束的判定 2.1、被错误使用的 feof 3、文件缓冲区 总结 1、文件的随机读写…

typescript学习(更新中)

目录 开发环境搭建类型如何声明有哪些类型编译配置文件 开发环境搭建 npm i -g typescripttsc检查是否安装成功 类型如何声明 // 先声明再赋值 let a: number a 1// 直接赋值 let b 1function sum(a: number, b: number): number {return a b } console.log(sum(1, 2))有…

VSCode搭建ARM开发环境

为了构建Cortex M系列单片机免费开源的开发环境&#xff0c;网络上了解来看VSCODEGCCJLINK是一套比较高效的组合方式&#xff0c;下面记录环境搭建的流程。 我这边的PC环境为 WIN7专业版64bit。 需要用到的工具 Visual Studio CodeSTM32CubemxARM GCC 交叉编译工具链&#x…

【刷题记录】详谈设计循环队列

下题目为个人的刷题记录&#xff0c;在本节博客中我将详细谈论设计循环队列的思路&#xff0c;并给出代码&#xff0c;有需要借鉴即可。 题目&#xff1a;LINK 循环队列是线性表吗&#xff1f;或者说循环队列是线性结构吗&#xff1f; 对于这个问题&#xff0c;我们来看一下线…

Vue 项目性能优化指南:提升应用速度与效率

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Qt插件之输入法插件的构建和使用(二)

文章目录 主键盘搭建Google开源引擎音节分割工具类参考项目下载搭建好各个基础控件之后,就可以开发输入法的主界面和引擎了,这也是输入法的核心。 主键盘搭建 输入法的主界面本质上是一个QStackedWidget容器,将各个类型的输入键盘插入到容器中,然后根据业务需要切换不同的…

图机器学习(4)-面向连接层面的人工特征工程

0 问题定义 通过已经连接去猜未知连接&#xff1a; 有两个思路&#xff1a; &#xff08;1&#xff09;直接提取link的特征&#xff0c;把link变成D维向量&#xff1b; &#xff08;2&#xff09;把link两端节点的D维向量拼在一起&#xff0c;缺点&#xff1a;丢失了link本身…