找出数组的第k大和
Posted 929code
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了找出数组的第k大和相关的知识,希望对你有一定的参考价值。
给你一个整数数组 nums 和一个正整数 k 。你可以选择数组的任一子序列并且对其全部元素求和。
数组的第 k 大和 定义为:可以获得的第 k 个 最大 子序列和(子序列和允许出现重复)
返回数组的第 k 大和
1. 转化问题 + 大根堆
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) //循环运行k-1次
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;
;
2. 二分
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());
--k;//
auto check = [&](long limit) -> bool
int cnt = 0;
//暴搜所有小于等于mid的序列和个数
function<void(int, long)> f = [&](int i, long s)
if (i == nums.size() || cnt >= k || s + nums[i] > limit) return; //边界条件
++cnt; //因为后面都可以不选,满足条件序列个数加一
f(i + 1, s + nums[i]); // 选
f(i + 1, s); // 不选
;
f(0, 0L);
return cnt >= k;
;
//求最大的结果,从数组中减去最小的序列,即有k个序列和满足值即可
long left = 0L, right = accumulate(nums.begin(), nums.end(), 0L);
while (left < right)
long mid = (left + right) / 2; //累计和
if (check(mid)) right = mid; //小于等于累计和的序列个数大于等于阈值
else left = mid + 1; //小于阈值,不满足条件
return sum - left; //减去对应累计和
;
Leetcode刷题100天—5855. 找出数组中的第 K 大整数(优先队列)—day22
前言:
作者:神的孩子在歌唱
大家好,我叫运智
5855. 找出数组中的第 K 大整数
难度中等1收藏分享切换为英文接收动态反馈
给你一个字符串数组 nums
和一个整数 k
。nums
中的每个字符串都表示一个不含前导零的整数。
返回 nums
中表示第 k
大整数的字符串。
**注意:**重复的数字在统计时会视为不同元素考虑。例如,如果 nums
是 ["1","2","2"]
,那么 "2"
是最大的整数,"2"
是第二大的整数,"1"
是第三大的整数。
示例 1:
输入:nums = ["3","6","7","10"], k = 4
输出:"3"
解释:
nums 中的数字按非递减顺序排列为 ["3","6","7","10"]
其中第 4 大整数是 "3"
示例 2:
输入:nums = ["2","21","12","1"], k = 3
输出:"2"
解释:
nums 中的数字按非递减顺序排列为 ["1","2","12","21"]
其中第 3 大整数是 "2"
示例 3:
输入:nums = ["0","0"], k = 2
输出:"0"
解释:
nums 中的数字按非递减顺序排列为 ["0","0"]
其中第 2 大整数是 "0"
提示:
1 <= k <= nums.length <= 104
1 <= nums[i].length <= 100
nums[i]
仅由数字组成nums[i]
不含任何前导零
package 优先队列;
import java.util.Arrays;
public class _5855_找出数组中的第K大整数 {
public String kthLargestNumber(String[] nums, int k) {
//自定义排序
Arrays.sort(nums, ((o1, o2) -> {
if (o1.length() > o2.length())
return -1;
else if (o1.length() < o2.length())
return 1;
else
return o2.compareTo(o1);
}));
return String.valueOf(nums[k - 1]);
}
}
本人csdn博客:https://blog.csdn.net/weixin_46654114
转载说明:跟我说明,务必注明来源,附带本人博客连接。
以上是关于找出数组的第k大和的主要内容,如果未能解决你的问题,请参考以下文章
Leetcode刷题100天—5855. 找出数组中的第 K 大整数(优先队列)—day22
Leetcode刷题100天—5855. 找出数组中的第 K 大整数(优先队列)—day22
Leetcode——找出数组中的第 K 大整数(字符串中数字排序)
LeetCode 5855. 找出数组中的第 K 大整数(自定义排序函数)
2021-06-01:K个逆序对数组。给出两个整数 n 和 k,找出所有包含从 1 到 n 的数字,且恰好拥有 k 个逆序对的不同的数组的个数。逆序对的定义如下:对于数组的第i个和第 j个元素,如果满