1.快速排序知识点回顾:
快速排序采用了一种分治的策略,通常称其为分治法(Divide-and-Conquer)。
平均时间复杂度为:O(nlogn)
最好时间复杂度为:O(nlogn), 每次找的基准数最佳,为每个区间的中值。
最坏时间复杂度为:O(n2), 数组递增或者递减。
空间复杂度:快速排序在系统内部需要一个栈来实现递归。若每次划分较为均匀,则其递归树的高度为 O(lgn), 故递归后所需栈 空间为 O(lgn) 。最坏情况下,递归树的高度为 O(n), 所需的栈空间为 O(n) 。
该方法的基本思想是:
1.先从数列中取出一个数作为基准数。
2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
3.再对左右区间重复第二步,直到各区间只有一个数。
快速排序代码:
int partition(int arr[], const int& left, const int& right)
{
if(left < right)
{
medianAsPivot(arr, left, right);
int i = left;
int j = right;
int key = arr[i]; // 首元素作为pivot
while(i < j)
{
while(i<j && arr[j]>=key) j--;
if(i < j) arr[i++] = arr[j];
while(i<j && arr[i]<key) i++;
if(i < j) arr[j--] = arr[i];
}
arr[i] = key;
return i;
}
return left;
}
// 快速排序递归实现
void quickSort(int arr[], const int& left, const int& right)
{
if(left < right)
{
int p = partition(arr, left, right);
quickSort(arr, left, p-1);
quickSort(arr, p+1, right);
}
}
2. Kth Largest Element :
http://www.lintcode.com/en/problem/kth-largest-element/
要接近O(n)的解法,必须每次选择区间的中值最为基准值。
void adjustPivot(vector<int> &nums, int left, int right)
{
int middle = (left & right) + ((left ^ right) >> 1);
if(nums[middle] >= min(nums[left], nums[right]) && nums[middle] <= max(nums[left], nums[right]))
swap(nums[left], nums[middle]);
else if(nums[right] >= min(nums[left], nums[middle]) && nums[right] <= max(nums[left], nums[middle]))
swap(nums[left], nums[right]);
}
int partition(vector<int> &nums, int left, int right)
{
if(left < right)
{
adjustPivot(nums, left, right);
int pivot = nums[left];
while(left < right)
{
while(left < right && nums[right] > pivot)
right--;
if(left < right) nums[left++] = nums[right];
while(left < right && nums[left] <= pivot)
left++;
if(left < right) nums[right--] = nums[left];
}
nums[left] = pivot;
}
return left;
}
int kthLargestElement(int k, vector<int> nums)
{
int size = nums.size();
if(k <= 0 || k > size)
return -1;
int left = 0;
int right = size - 1;
while(true)
{
int position = partition(nums, left, right);
if(position < size-k) left = position + 1;
else if(position > size-k) right = position - 1;
else return nums[size - k];
}
}