问题描述:
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
说明:
你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-largest-element-in-an-array
解决思路:
寻找最大数,然后接着寻找次大的数,直到遇见K
我列举三种方案:
(1)初级解决方案:将所有数无脑排序 https://blog.csdn.net/qq_39731011/article/details/95457842
(2)中级解决方案: 1.转List。2.遍历找到当前最大数并删除。3.重复第2步,重复次数=k次
(3)高级解决方案:
扫描二维码关注公众号,回复:
11646722 查看本文章
1.找到最大数,把(长度减循环次数)的数赋给当前最大数。
2.下一次遍历范围缩小(长度减循环次数)
3.重复第1、2步,重复次数=k次
总结:
深海能力和时间有限,更高级的方式就不说了。
总之,优化的中心思想是:缩小遍历跨度,缩短执行次数。
方案(3)相对于(2)少了一个转集合的过程,推荐采用!
具体代码:
方案(1):https://blog.csdn.net/qq_39731011/article/details/95457842
方案(2):
/*
*作者:赵星海
*时间:2020/8/22 9:34
*用途:数组中的第K个最大元素
*/
public int findKthLargest(int[] nums, int k) {
//首先要明白一件事:从大到小找数,没有必要把全部的数都排序
//具有部分选择排序的思想:https://blog.csdn.net/qq_39731011/article/details/95457842
ArrayList<Integer> list = new ArrayList<>();
for (int i : nums) {
list.add(i);
}
//每次循环后的最大数 因为有可能数组中全部是负数,所以这里this的默认值不可以是0
int thisBig = nums[0];
int thisBigIndex = 0;
for (int i = 0; i < k; i++) {
//找到当前最大数并删除该数,直到遇见第k个元素
for (int j = 0; j < list.size(); j++) {
if (list.get(j) >= thisBig) {
thisBig = list.get(j);
thisBigIndex = j;
}
}
//这边表示执行到了第k个元素
if (i == k - 1) {
return thisBig;
}
list.remove(thisBigIndex);
thisBig = list.get(0);
thisBigIndex = 0;
}
return 0;
}
方案(3):
/*
*作者:赵星海
*时间:2020/8/22 9:34
*用途:数组中的第K个最大元素
*/
public int findKthLargest(int[] nums, int k) {
//首先要明白一件事:从大到小找数,没有必要把全部的数都排序
//具有部分选择排序的思想:https://blog.csdn.net/qq_39731011/article/details/95457842
//每次循环后的最大数 因为有可能数组中全部是负数,所以这里this的默认值不可以是0
int thisBig = nums[0];
int thisBigIndex = 0;
for (int i = 0; i < k; i++) {
//找到当前最大数并将最后的数替换掉它,直到遇见第k个元素
for (int j = 0; j < nums.length - i; j++) {
if (nums[j] >= thisBig) {
thisBig = nums[j];
thisBigIndex = j;
}
}
//这边表示执行到了第k个元素
if (i == k - 1) {
return thisBig;
}
//后数前移替换
nums[thisBigIndex] = nums[nums.length - 1 - i];
thisBig = nums[0];
thisBigIndex = 0;
}
return 0;
}