该题最直观的解决思路是先对数组进行排序,然后返回第k个元素即可,但是该方法的时间复杂度为 O(nlog(n)), 较高。比较高校的思路有两种:一种是堆排序的思路,一种是快拍的思路。
一、堆排序的思路。该思路设置容量为 k 的小顶堆,将剩余的元素每一个和堆顶元素进行比较,若比堆顶元素小则该元素必然不会是第 k 大的元素,直接处理下一个元素;若比堆顶元素大则说明堆顶元素不可能是第 k 大的元素,替换堆顶元素与该元素,调整堆。 每调整一次堆的时间复杂性为 O(log(k)),总共有 n 个元素,则该思路的总时间复杂度为:O(n(log(k)))。
int findKthLargest(vector<int>& nums, int k){ int len = nums.size(); int i = (k - 1 - 1)/2; int tmp; //调整初始堆 while(i >= 0){ int tmpi = i; tmp = nums[i]; int j = i*2 + 1; while(j < k){ if(j+1 < k && nums[j+1] < nums[j]) j++; if(nums[j] >= tmp) break; nums[i] = nums[j]; i = j; j = i*2 + 1; } nums[i] = tmp; i = tmpi - 1; } //遍历剩余元素 for(int l = k; l < len; l++){ if(nums[l] <= nums[0]) continue; nums[0] = nums[l]; tmp = nums[0]; i = 0; int j = i*2 + 1; while(j < k){ if(j + 1 < k && nums[j + 1] < nums[j]) j++; if(nums[j] >= tmp) break; nums[i] = nums[j]; i = j; j = i*2 + 1; } nums[i] = tmp; } return nums[0]; }
二、快排的思路。该思路根据快速排序的思路进行处理,首先选择数组首元素 A 进一次快排处理,使得比它小的元素都在其前面比它大的元素都在其后面,处理之后若 A 此时的位置在第 k 个位置,则直接返回,否则若比 k 小,则对其之后的元素进行同样的处理,若比 k 大则对其之前的元素进行同样的处理。直到某一次处理的元素其位置就在第 k 个元素的位置返回即可。该思路最坏情况下需要对一半的数据进行排序,时间复杂度是 O(n(log(n))),但一般情况下时间复杂度要小的多。
//快排思路 int kthlargest(vector<int>& nums, int i, int j, int k){ int start = i; int end = j; int tmp; while(start < end){ tmp = nums[start]; while(start < end && nums[end] < tmp) end--; nums[start] = nums[end]; nums[end] = tmp; while(start < end && nums[start] > tmp) start++; nums[end] = nums[start]; nums[start] = tmp; } if( start == k - 1) return nums[start]; else{ if(start < k - 1){ return kthlargest(nums, start + 1, j, k); }else{ return kthlargest(nums, i, start - 1, k); } } } int findKthLargest(vector<int>& nums, int k){ int len = nums.size(); return kthlargest(nums, 0, len - 1, k); }<span id="_xhe_cursor"> </span>
版权声明:本文为博主原创文章,未经博主允许不得转载。
Kth Largest Element in an Array
原文地址:http://blog.csdn.net/ny_mg/article/details/48087763