算法题目 : 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.
算法分析:
这道题很好理解,就是求一个数组中的第k大的数字,首先想到的当然就是排序了,直接用sort()函数就可以排序,然后在返回第K大的数。然而考虑到算法的效率,这样肯定不行,需要用到其他排序算法。我们一般用到的排序算法有插入排序,快速排序,选择排序,归并排序等,各有各的优势。这里面和分治算法相关的就只有快速排序和归并排序了。
下面我们主要探讨归并排序和快速排序。对于归并排序,归并过程为:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。
时间复杂度为 O( n log n) 空间复杂度为 O(n) 对于快速排序算法来说,它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。通过对比我们可以很清楚的看到两者的时间复杂性是一样的,但是实际上用起来还是快速排序更胜一筹。这其中的主要原因还是要自己做实验来分析的,一般的解释是当数据量越来越大时,尽管归并排序的比较次数较少,但是归并排序后期的合并操作所花费的时间便越来越大,合并操作对整体的效率影响越来越明显,包括后面大量数据的赋值操作等。所以当数据量变大时,不需要专门合并的快速排序的优势就变得越发明显。归并排序比快速排序有优势的一点估计就是稳定性了。所以在权衡下,最终选取了快速排序。快速排序肯定都不陌生,就直接上代码吧!
算法代码(C++):
class Solution {
public:
void quicksort(vector<int>& nums, int left, int right)
{
if(left < right)
{
int pivot = nums[left];
int low = left;
int high = right;
while(low < high)
{
while(low < high && nums[high] >= pivot)
high--;
nums[low] = nums[high];
while(low < high && nums[low] <= pivot)
low++;
nums[high] = nums[low];
}
nums[low] = pivot;
quicksort(nums, left, low - 1);
quicksort(nums, low + 1, right);
}
}
int findKthLargest(vector<int>& nums, int k) {
quicksort(nums, 0, nums.size() - 1);
return nums[nums.size() - k];
}
};