LintCode笔记(12)——第k大元素
来源:互联网 发布:知乎关于六小龄童 编辑:程序博客网 时间:2024/04/30 04:52
在数组中找到第k大的元素
注意事项
你可以交换数组中的元素的位置
样例
给出数组 [9,3,2,4,8]
,第三大的元素是 4
给出数组 [1,2,3,4,5]
,第一大的元素是 5
,第二大的元素是 4
,第三大的元素是 3
,以此类推
挑战
这道题需要利用快速排序的思想,首先复习一下什么是快速排序。要求时间复杂度为O(n),空间复杂度为O(1)
快速排序算法的主要思想为以下几步:
(1)首先选中一个基准数;
(2)在数组中进行排序,使得比基准数小的全在他左边,比基准数大的全在他右边;
(3)对上面得到的左右区间分别执行(2)中操作,直到最终区间的数字只有一个为止。
下面对快速排序算法进行详细的解释:有如下所示的数组
01234563251803假定我们选择数组的第0个元素作为基准数X且按从小到大的顺序进行排序,有初始时i = 0 ,j = 6,X = nums[i]
首先判断nums[j] >= X吗,如果成立,则不动他同时有j--寻找下一个,如果不成立,则nums[i] = nums[j];同时i++
然后判断nums[i] < X吗,如果成立,则不动他,同时有i++寻找下一个,如果不成立,则nums[j] = nums[i];同时j--
这样操作直到i>=j为止,此时数组中比X小的在他左边,比他大的在他右边。
然后分别对得到的左右区间如此操作,直到最后区间的大小为1为止。
这个博客对快速排序讲得很详细
具体的快速排序的代码如下所示(从小到大排序):
int quickSort(vector<int> &numList, int left, int right){if (left < right)//判断left到right的这个区间是否已经排序完成{//对left到right的这个区间进行排序int i = left;int j = right;int tmp = numList[left];while (i < j)//当i>=j时,排序完成{while (i < j && tmp <= numList[j])//从数组末尾开始找,直到找到比基准数tmp小的数{j--;}if (i < j)//判断前面的循环跳出是因为没有找到还是找到了比tmp小的数{numList[i++] = numList[j];//若找到了}while (i<j && tmp > numList[i])//从数组开头开始找,直到找到比基准数tmp大的数{i++;}if (i < j)//判断前面的循环跳出是因为没有找到还是找到了比tmp大的数{numList[j--] = numList[i];//若找到了}}numList[i] = tmp;quickSort(numList, left, i - 1);quickSort(numList, i + 1, right);}}
说完了快速排序,那么如何解决这道题呢
对数组利用快速排序从大到小排序的思想,找到每一次快速排序时基准数的下标(基准数的下标即为排序好后该数的真实下标),直到找到下标为k-1的数为止。(具体怎么算时间复杂度我也不太清楚,还要学习,网上说这种算法的时间复杂度为O(n))
具体代码如下:
int quickSort(vector<int> &numList, int left, int right){//对left到right的这个区间进行排序int i = left;int j = right;int tmp = numList[left];while (i < j)//当i>=j时,排序完成{while (i < j && tmp >= numList[j])//注意与前面不一样{j--;}if (i < j){numList[i++] = numList[j];}while (i<j && tmp < numList[i])//注意与前面不同{i++;}if (i < j){numList[j--] = numList[i];}}numList[i] = tmp;return i;//返回基准数下标}int kthLargestElement(int k, vector<int> nums) {// write your code hereif (nums.size() == 0)return 0;int left = 0;int right = nums.size() - 1;while (1){int pos = quickSort(nums, left, right);if (pos == k - 1)//若找到的基准数下标为k-1,即为结果{return nums[k - 1];}if (pos > k - 1)//若找到的基准数下标比k-1大,则从其左区间中继续寻找,丢弃其右区间{right = pos - 1;}if (pos < k - 1)//若找到的基准数下标比k-1小,则从其右区间中继续寻找,丢弃其左区间{left = pos + 1;}}}
0 0
- LintCode笔记(12)——第k大元素
- LintCode 第K大元素
- LintCode-第k大元素
- 【LintCode】第k大元素
- lintcode&九章算法——lintcode NO.5 第k大元素 ? 带解决
- LintCode 5 第K大元素
- LintCode Python 第k大元素
- [LintCode]5.第k大元素
- LintCode 中位数/第K大元素
- LintCode之5 第k大元素
- Lintcode 5. 第k大元素
- (lintcode)第5题第k大元素
- lintcode-第k大元素-197(堆的实现)
- LintCode-剑指Offer-(5)第k大元素
- [LintCode] 第K大元素 Kth Largest Element
- 第k大元素
- 第k大元素
- 第k大元素
- instanceof什么时候使用?
- SecureCRT之rz:command not found
- js里实现继承的几种方式
- android html5网页定位
- App 创业者的福音,应用质量问题将完美解决
- LintCode笔记(12)——第k大元素
- 深入理解 spl_autoload , __autoload 以及 spl_autoload_register
- 【Android】SystemBarTintManager沉侵式菜单栏
- android studio | openGL es 3.0增强现实(AR)开发 (2) .so文件的应用和理解
- IO流总结
- 全文检索Lucene (2)
- ffmpeg初探
- 继承
- http协议的一些知识点