本题是一道经典的算法题,也是facebook、MicroSoft、amazon、Bloomberg、Apple的面试题。
问题描述:
(1)首先,我们定义一个随机数组,查找数组中第二大的元素:
vector<int> nums1 = { 3, 2, 1, 5, 6, 4 };
cout << Solution().findKthLargest(nums1, 2) << endl;
(2)对数组进行排序,使的数组由大到小排列,下标为k-1的元素即为数组中第k大元素
public:
int findKthLargest(vector<int>& nums, int k) {
return __findKthLargest(nums, 0, nums.size() - 1, k - 1);
}
(3)函数__findKthLargest
private:
int __findKthLargest(vector<int>& nums, int l, int r, int k) {
if (l == r)
return nums[l];
int p = partition(nums, l, r);
if (p == k)
return nums[p];
else if (k < p)
return __findKthLargest(nums, l, p - 1, k);
else // k > p
return __findKthLargest(nums, p + 1, r, k);
}
(4)函数partition()的实现-使用快速排序法
type:
我们选择一个随机数组 { 3, 2, 1, 5, 6, 4 },选择第一个元素为标定点 p = 3;
定义慢指针int lt = l + 1;
快指针:int i = l + 1;
遍历数组
第一轮遍历:
① if (nums[i] <= nums[l])
则i++;
② if (nums[i] > nums[l])
swap(nums[i], nums[lt]);
然后Lt++,i++
遍历完成后:
最后,swap(nums[l], nums[lt - 1]);
return lt - 1;
所以,函数partition返回3。
此时 p = 3,k = 1;
if (k < p)
return __findKthLargest(nums, l, p - 1, k);
进行第二轮遍历:
遍历完成后的到的数组
return lt - 1; 所以p =2 .
进行第三轮遍历:
遍历完成后:
return lt - 1; 所以 p = 0;
if(k > p)
return __findKthLargest(nums, p + 1, r, k);
此时,__findKthLargest(nums,1, 1, 1)
所以: if (l == r)
return nums[l];
nums[1] = 5;
完成了整个数组的查找!
完整的源代码:
#include <iostream>
#include <vector>
#include <cassert>
#include <stdexcept>
#include <ctime>
using namespace std;
/// Quick Sort Partition.
/// Time Complexity: O(n)
/// Space Complexity: O(1)
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
srand(time(NULL));
return __findKthLargest(nums, 0, nums.size()-1 , k - 1 );
}
private:
int __findKthLargest( vector<int>& nums, int l, int r, int k ){
if( l == r )
return nums[l];
int p = partition( nums, l, r );
if( p == k )
return nums[p];
else if( k < p )
return __findKthLargest( nums, l, p-1, k);
else // k > p
return __findKthLargest( nums, p+1 , r, k );
}
int partition( vector<int>& nums, int l, int r ){
int p = rand()%(r-l+1) + l;
swap( nums[l] , nums[p] );
int lt = l + 1; //[l+1...lt) > p ; [lt..i) < p
for( int i = l + 1 ; i <= r ; i ++ )
if( nums[i] > nums[l] )
swap(nums[i], nums[lt++]);
swap(nums[l], nums[lt-1]);
return lt-1;
}
};
int main() {
vector<int> nums1 = {3, 2, 1, 5, 6, 4};
cout << Solution().findKthLargest(nums1, 2) << endl;
vector<int> nums2 = {3, 1, 2, 4};
cout << Solution().findKthLargest(nums2, 2) << endl;
vector<int> nums3 = {3, 3, 3, 3, 3, 3, 3, 3, 3};
cout << Solution().findKthLargest(nums3, 8) << endl;
return 0;
}
<全文完>
参考资料: