1. 题目

在未排序的数组中找到第 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 ≤ 数组的长度。

2. 思路

  • 针对这个题目,我们首先想到的就是先用排序算法对数据从大到小进行排序,然后直接返回降序后的第 K 个元素即可。

  • 另外,我们也可以借鉴快速排序的思想。每次选取一个 pivot,将大于 pivot 的数放在 pivot 左边,将小于 pivot 的数放在 pivot 右边。

  • 这时候,如果 pivot 正好是第 K 个数据,则 pivot 就是数组中的第 K 个最大元素。

  • 如果 pivot 所在的位置小于 K ,则说明数组中的第 K 个最大元素位于 pivot 的右边。此时,假设 pivot 的位置为 which_max,which_max 是几就代表 pivot 是数组中的第几个最大元素。这时候,我们再从 pivot 右边的数据中找到第 (K-which_max) 个最大元素即可。

  • 如果 pivot 所在的位置大于 K ,则说明数组中的第 K 个最大元素位于 pivot 的左边。这时候,pivot 左边的数据全部大于 pivot,我们继续从 pivot 左边的数据中找第 K 个最大元素即可。

  • 而其中的快速排序算法实现可以有两种思想,具体可参考此处

class Solution {
public:
int findKthLargest(vector<int>& nums, int k) { return quick_sort(nums, 0, nums.size()-1, k);
} // 第一种快排思想
int quick_sort(vector<int>& data, int left, int right, int k)
{
int i = left;
int j = right;
int pivot = data[right];
int len = right - left + 1; if (left < right)
{
// 从大到小对数组进行快排
while(i < j)
{
while(i < j && data[i] >= pivot) // 从左往右找第一个比 pivot 小的数
{
i++;
}
if (i < j)
{
data[j--] = data[i];
} while(i < j && data[j] <= pivot) // 从右往左找第一个比 pivot 大的数
{
j--;
}
if (i < j)
{
data[i++] = data[j];
}
} data[i] = pivot; // 此时 i == j // pivot 此时位于索引 i 处,i - left + 1 表示 pivot 是第几大的数
int which_max = i - left + 1;
if (which_max == k) // pivot 正好是第 k 大的数
{
return pivot;
} // 第 k 大的数在 pivot 右边,问题转化为找右边数组第 (k - which_max) 大的元素
// 比如 pivot 是第四大的数,要找第五大的数,则继续找右边数组第一大的数即可
else if(which_max < k)
{
return quick_sort(data, i + 1, right, k - which_max);
} // 第 k 大的数在 pivot 左边,问题转化为找左边数组第 k 大的元素
// 比如 pivot 是第三大的数,要找第二大的数,则继续找左边数组第二大的数即可
else
{
return quick_sort(data, left, i - 1, k);
}
}
else
{
return pivot;
}
} // 第二种快排思想
int quick_sort(vector<int>& data, int left, int right, int k)
{
int i = left;
int j = left;
int pivot = data[right];
int len = right - left + 1; if (left < right)
{ // 从大到小对数组进行快排
for (; j < right; j++)
{
if (data[j] > pivot)
{
int temp = data[i];
data[i] = data[j];
data[j] = temp;
i++;
}
} data[j] = data[i];
data[i] = pivot; // pivot 此时位于索引 i 处,i - left + 1 表示 pivot 是第几大的数
int which_max = i - left + 1;
if (which_max == k) // pivot 正好是第 k 大的数
{
return pivot;
} // 第 k 大的数在 pivot 右边,问题转化为找右边数组第 (k - which_max) 大的元素
// 比如 pivot 是第四大的数,要找第五大的数,则继续找右边数组第一大的数即可
else if(which_max < k)
{
return quick_sort(data, i + 1, right, k - which_max);
} // 第 k 大的数在 pivot 左边,问题转化为找左边数组第 k 大的元素
// 比如 pivot 是第三大的数,要找第二大的数,则继续找左边数组第二大的数即可
else
{
return quick_sort(data, left, i - 1, k);
}
}
else
{
return pivot;
}
}
};

获取更多精彩,请关注「seniusen」!

LeetCode 215——数组中的第 K 个最大元素的更多相关文章

  1. Java实现 LeetCode 215. 数组中的第K个最大元素

    215. 数组中的第K个最大元素 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6 ...

  2. Leetcode 215.数组中的第k个最大元素

    数组中的第k个最大元素 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 ...

  3. [LeetCode]215. 数组中的第K个最大元素(堆)

    题目 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 输出 ...

  4. Leetcode 215. 数组中的第K个最大元素 By Python

    在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 输出: 5 ...

  5. LeetCode 215. 数组中的第K个最大元素(Kth Largest Element in an Array)

    题目描述 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 ...

  6. leetcode 215. 数组中的第K个最大元素(python)

    在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2输出: 5示 ...

  7. LeetCode:数组中的第K个最大元素【215】

    LeetCode:数组中的第K个最大元素[215] 题目描述 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: ...

  8. 215. 数组中的第K个最大元素 + 快速排序 + 大根堆

    215. 数组中的第K个最大元素 LeetCode-215 另一道类似的第k大元素问题:https://www.cnblogs.com/GarrettWale/p/14386862.html 题目详情 ...

  9. Leetcode题目215.数组中的第K个最大元素(中等)

    题目描述: 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 ...

随机推荐

  1. input按钮选择功能

    <p> <input type="checkbox" class="ischecked" id="is_pinkage" ...

  2. some small knowledge

    cookie 增查 <!--1.语义化标签的作用--> <!--1.1 从开发角度考虑是提高代码的可读性可维护性--> <!--1.2 网站的发布者:seo 搜索引擎优化 ...

  3. Java数据结构——二叉树 增加、删除、查询

    //二叉树系统 public class BinarySystem { public static void main(String[] args) { BinaryDomain root = nul ...

  4. 轻量ORM-SqlRepoEx (四)INSERT、UPDATE、DELETE 语句

    *本文中所用类声明见上一篇博文<轻量ORM-SqlRepoEx (三)Select语句>中Customers类 一.增加记录 1.工厂一个实例仓储 var repository = Rep ...

  5. JavaScript 基础(四) 循环

    JavaScript的循环有两种,一种是for 循环,通过初始条件,结束条件和递增条件来循环执行语句块: var x = 0; var i; for(i=1; i <=10000; i++){ ...

  6. 创建私有CA并签发证书

    一.创建私有CA 1.创建所需要的文件 2.创建私有密钥 3.CA自签证书 -new: 生成新证书签署请求:               -x509: 专用于CA生成自签证书:不自签的时候不要加该选项 ...

  7. 汇编:模拟C语言实现break与continue

    ;=============================== ;循环程序设计 ;模拟C语言实现break 与continue DATAS SEGMENT i dw sum dw DATAS end ...

  8. python爬虫 爬取steam热销游戏

    好久没更新了啊...最近超忙 这学期学了学python 感觉很有趣 就写着玩~~~ 爬取的页面是:https://store.steampowered.com/search/?filter=globa ...

  9. Intellij 出现“Usage of API documented as @since 1.4+”的解决办法

    https://blog.csdn.net/wust_lh/article/details/73277185

  10. HyperLedger Fabric 1.4 超级账本简介(5.2)

    超级账本(Hyperledger)是推动区块链跨行业应用的开源项目的总称,组织成员可以发起新的区块链项目,加入到超级账本项目(Hyperledger)中,但需要遵循Hyperledger的生命周期.  ...