刚开始做的时候想法就是先把最大和求出来,然后再删掉一些数。

求最大的只要遍历一遍,正数都加起来就可以了。

接下来要删掉一些数,为了让正数和负数统一,我把所有正数都翻转成了负数,这样当删去一个数时就可以直接加而不需要分正数和负数判断。

再接下来就不知道要怎么做了,然后看了题解。

要找出前k大的和,那么对于目前已经求出正数和,并且所有正数都翻转成了负数的情况而言,就需要在绝对值比较小的数(由于都是非正数,所以也就是较大的数)中找一些数作为要加上的数。

用优先队列存sum和下一个要处理的位置,按sum降序排列。当处理到第i个数时,为了让所有的情况都被考虑到,要向优先队列存入加上i-1的和没有加上i-1的值。

例如有三个数,用二进制位来分别表示它们,则:

#mermaid-svg-5jj4nW8Zhn1hWufn {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-5jj4nW8Zhn1hWufn .error-icon{fill:#552222;}#mermaid-svg-5jj4nW8Zhn1hWufn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5jj4nW8Zhn1hWufn .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-5jj4nW8Zhn1hWufn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5jj4nW8Zhn1hWufn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5jj4nW8Zhn1hWufn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5jj4nW8Zhn1hWufn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5jj4nW8Zhn1hWufn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5jj4nW8Zhn1hWufn .marker.cross{stroke:#333333;}#mermaid-svg-5jj4nW8Zhn1hWufn svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5jj4nW8Zhn1hWufn .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-5jj4nW8Zhn1hWufn .cluster-label text{fill:#333;}#mermaid-svg-5jj4nW8Zhn1hWufn .cluster-label span{color:#333;}#mermaid-svg-5jj4nW8Zhn1hWufn .label text,#mermaid-svg-5jj4nW8Zhn1hWufn span{fill:#333;color:#333;}#mermaid-svg-5jj4nW8Zhn1hWufn .node rect,#mermaid-svg-5jj4nW8Zhn1hWufn .node circle,#mermaid-svg-5jj4nW8Zhn1hWufn .node ellipse,#mermaid-svg-5jj4nW8Zhn1hWufn .node polygon,#mermaid-svg-5jj4nW8Zhn1hWufn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5jj4nW8Zhn1hWufn .node .label{text-align:center;}#mermaid-svg-5jj4nW8Zhn1hWufn .node.clickable{cursor:pointer;}#mermaid-svg-5jj4nW8Zhn1hWufn .arrowheadPath{fill:#333333;}#mermaid-svg-5jj4nW8Zhn1hWufn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5jj4nW8Zhn1hWufn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5jj4nW8Zhn1hWufn .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-5jj4nW8Zhn1hWufn .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-5jj4nW8Zhn1hWufn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5jj4nW8Zhn1hWufn .cluster text{fill:#333;}#mermaid-svg-5jj4nW8Zhn1hWufn .cluster span{color:#333;}#mermaid-svg-5jj4nW8Zhn1hWufn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5jj4nW8Zhn1hWufn :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

100
101
110
111
000
001
011
010

可以看到所有八种情况都被考虑到了。

由于我们只需要从优先队列里取k个数,而每次最多也只推入两个数,所以它贡献的复杂度也只是O(klogk)O(klogk)O(klogk)。

class Solution {public:
#define plli pair<long long,int>long long kSum(vector<int>& nums, int k) {long long sum=0;int sz=nums.size();for(int i=0;i<sz;++i){if(nums[i]>0){sum+=nums[i];nums[i]=-nums[i];}}sort(nums.begin(),nums.end(),[](int a,int b){return a>b;});priority_queue<plli> q;q.push(plli(sum,0));while(--k){plli p=q.top();q.pop();if(p.second<sz){q.push(plli(p.first+nums[p.second],p.second+1));if(p.second)q.push(plli(p.first+nums[p.second]-nums[p.second-1],p.second+1));}}return q.top().first;}
};

感觉这个是取子序列的又一个重要方法。

LC2386. 找出数组的第 K 大和相关推荐

  1. 找出数组中第k大和第m大的数字之和

    找出数组中第k大和第m大的数字之和 说明:定义一个函数,接受三个参数getMaxNumber(array,k,m){},找出第k大和第m大的数字之和.重复的数组也需要计算 比如:[1,3,4,5,4, ...

  2. 找出数组中第k大小的数,输出数所在的位置

    找出数组中第k大小的数,输出数所在的位置 /*写一段程序,找出数组中第k大小的数,输出数所在的位置.例如{2,4,3,4,7}中,第一大的数是7,位置在4. 第二大.第三大的数都是4,位置在1.3随便 ...

  3. 找出数组中第k大的数

    给定一个数组,找出数组中第k大的数.其实现代码如下: package com.threeTop.www;/*** 找出数组中第k大的数* @author wjgs**/ public class Fi ...

  4. Java找出数组中第K大的数

    题目描述 有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数. 给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在. 测试样例: [1,3,5 ...

  5. 【leetcode】找出数组的第k大的数

    用快排,原始的快排 def quick_sort(nums,l,r):if l<=r:returntmp = nums[0]while l<r: while l<r and nums ...

  6. 分治法 第3关:找出数组中第 k 个小的元素

    任务描述 本关任务:对于给定的 n 个元素的数组a[0:n-1],要求从中找出第 k 小的元素. 编程要求 请在右侧编辑器Begin-End处补充代码,完成本关任务,注意需要学生自己获取输入数据再进行 ...

  7. 1985. 找出数组中的第 K 大整数

    1985. 找出数组中的第 K 大整数 给你一个字符串数组 nums 和一个整数 k .nums 中的每个字符串都表示一个不含前导零的整数. 返回 nums 中表示第 k 大整数的字符串. 注意:重复 ...

  8. 找出数组中出现次数超过一半的数

    算法--找出数组中出现次数超过一半的数      每当我看到经典的算法题,就怀念高中,感觉很多算法题就是高中的题目,谁叫哥只读了个专科,高数基本相当没学.      有空要看看高数啊,想当年数学那是相 ...

  9. 微策略2011校园招聘笔试题(找出数组中两个只出现一次的数字)

    1.8*8的棋盘上面放着64个不同价值的礼物,每个小的棋盘上面放置一个礼物(礼物的价值大于0),一个人初始位置在棋盘的左上角,每次他只能向下或向右移动一步,并拿走对应棋盘上的礼物,结束位置在棋盘的右下 ...

最新文章

  1. VS恢复默认设置的2种方法
  2. Microsoft Fluent Design System
  3. java ee jaas_java-ee – Tomcat-Jaas – 如何检索主题?
  4. python 对象转dict_python model对象转为dict数据
  5. nmap +shell脚本实现内网端口巡检
  6. macOS big Sur 无限进入恢复模式,如何修复
  7. 海康威视监控视频,萤石云免费版四路并发访问限制绕过
  8. 基于javaweb+mysql的在线购书商城系统(java+jsp+mysql+servlert+ajax)
  9. 你不知道流量宝的神操作就能免费增加20万网站PV浏览量
  10. 微信小程序Demo大全
  11. 矩阵卷积、矩阵相乘以及频域相乘之间的关系
  12. 50个最新漂亮的国外网站模板下载
  13. 计算机基础知识表格斜线,怎么在excel中画斜线-制作好看的Excel表格必备技能:3秒制作斜线表头,简单到没朋友...
  14. 【哈佛幸福课·健康之道】锻炼的真相
  15. SQL分组选取时间最大的记录
  16. 阿里云直播鉴权和直播地址算法
  17. for循环去掉最后一个逗号(三种方法)
  18. iphone12android在线,【苹果iPhone12评测】安卓机吃尽高刷红利,为何iPhone 12还是缺席?(全文)_苹果 iPhone 12_手机评测-中关村在线...
  19. 双十一大促客服必备话术
  20. error: previous declaration of '****' was here

热门文章

  1. 短整型转字符数组,字符数组转短整型
  2. ultraiso制作u盘系统linux,使用UltraISO制作ubuntu安装u盘启动盘图文教程
  3. java集成测试_到底什么是集成测试?
  4. Pandas操作CSV文件的读写
  5. 矩阵消元-线性代数课时2(MIT Linear Algebra , Gilbert Strang)
  6. 视觉 SLAM 十四讲 —— 第十三讲 建图
  7. 科大讯飞举办翻译战略暨新品发布会,讯飞翻译机2.0正式上市
  8. sele.request -102 参数timestamp异常,请检查后重试
  9. 富士施乐DocuPrint m115b加粉后粉盒和硒鼓清零方法
  10. Flow Chart Maker Online Diagram Software | Lucidchart