[LeetCode] Kth Largest Element in an Array

https://leetcode.com/problems/kth-largest-element-in-an-array/

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.

For example,
Given [3,2,1,5,6,4] and k = 2, return 5.

Note:
You may assume k is always valid, 1 ≤ k ≤ array's length.

方法2 使用大顶堆，进行Heap Select

/**
* Author : Jianxin Zhou
*/

class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
heapSize_ = nums.size();

createMaxHeap(nums);
for (int i = 0; i < k - 1; ++i) {
exactMax(nums);
}

return nums[0];
}

private:
int heapSize_;

inline int leftChild(int parent) {
return (parent << 1) + 1;
}

inline int rightChild(int parent) {
return (parent << 1) + 2;
}

inline int parent(int child) {
return (child - 1) >> 1;
}

void createMaxHeap(vector<int> &nums) {
int indexForHeapify = parent(heapSize_ - 1);
for (int i = indexForHeapify; i >= 0; --i) {
maxHeapify(nums, i);
}
}

// 从位置i处进行下滤，保持大顶堆的偏序性
void maxHeapify(vector<int> &nums, int i) {
int left = leftChild(i);
int right = rightChild(i);
int largest = i;

if (left < heapSize_ && nums[left] > nums[largest]) {
largest = left;
}

if (right < heapSize_ && nums[right] > nums[largest]) {
largest = right;
}

if (largest != i) {
swap(nums[largest], nums[i]);
maxHeapify(nums, largest);
}
}

void exactMax(vector<int> &nums) {
swap(nums[0], nums[heapSize_ - 1]);
--heapSize_;
maxHeapify(nums, 0);
}
};

方法3 使用QuickSelect

class Solution {
public:
int findKthLargest(vector<int> &nums, int k) {
return quickSelect(nums, 0, nums.size() - 1, k);
}

private:
int quickSelect(vector<int> &nums, int left, int right, int k) {
int pivot = right;
int i = left - 1;

// 遍历数组，将当前数组中数值大于pivot位置的元素均移至数组开始
// 那么当遍历结束时，++i位置的元素即为pivot元素应该在的位置
for (int j = left; j < right; j++) {
if (nums[j] > nums[pivot]) {
swap(nums[++i], nums[j]);
}
}
swap(nums[pivot], nums[++i]);

// 递归基
if (i - left + 1 == k) {
return nums[i];
}

if (i - left + 1 > k) {
return quickSelect(nums, left, i - 1, k);
} else if (i - left + 1 < k) {
return quickSelect(nums, i + 1, right, k - (i - left + 1));
}
}
};
posted @ 2015-07-25 16:25  Acjx  阅读(578)  评论(0编辑  收藏  举报