快速排序
基于labuladong的算法网站,快速排序详解及应用
1、快速排序算法思路
代码:
// 在数组nums将下标从left到right中进行从小到大排序
// 原理是先将一个元素排好序,然后将其他的元素排好序
void sort(int[] nums, int left, int right) {
if (left >= right) {
return;
}
// 对数组nums[left,right]进行切分,使得nums[left,p-1]<=nums[p]<=nums[p+1,right]
int p = partition(nums, left, right);
// 去左右数组进行切分
sort(nums, left, p - 1);
sort(nums, p - 1, right);
}
// 在数组中nums[left,right]中寻找到一个分界点p
int partition(int[] nums, int left, int right) {
// 将数组中最左边的元素放入正确的位置后,返回该位置
int pivot = nums[left];
// 最后数组被分为三个区间,[left,i)和i和(j,right]
int i = left + 1, j = right;
while (i <= j) {
// i右移找大于pivot的数
while (i < right && nums[i] <= pivot) {
i++;
}
// j左移找到小于pivot的数
while (j > left && nums[j] >= pivot) {
j--;
}
// 判断此时的i和j是否越界
if (i >= j) {
break;
}
swap(nums, i, j);
}
// 最后将pivot和j进行交换
swap(nums, left, j);
return j;
}
// 将元素随机打乱
void shuffle(int[] nums) {
int len = nums.length;
Random random = new Random();
for (int i = 0; i < len; i++) {
// 生成[i,len-1]之间的随机数
int index = i + random.nextInt(len - i);
swap(nums, i, index);
}
}
void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
2、数组中的第K大个元素
力扣第215题,数组中的第K大个元素
- 解法一:优先级队列
[215]数组中的第K个最大元素
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public int findKthLargest(int[] nums, int k) {
// 利用优先级队列,自动是小根堆
PriorityQueue<Integer> queue = new PriorityQueue<>();
for (int i = 0; i < k; i++) {
queue.add(nums[i]);
}
for (int i = k; i < nums.length; i++) {
if (nums[i] > queue.peek()) {
queue.poll();
queue.add(nums[i]);
}
}
return queue.peek();
}
}
//leetcode submit region end(Prohibit modification and deletion)
- 解法二:快速排序
[215]数组中的第K个最大元素
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
// 利用快速排序
public int findKthLargest(int[] nums, int k) {
// 首先将数组进行打乱,优化一下算法
shuffle(nums);
int left = 0, right = nums.length - 1;
// 转化成寻找第k个最小的元素
k = nums.length - k;
while (left <= right) {
int p = partition(nums, left, right);
if (p == k) {
return nums[p];
} else if (k < p) {
right = p - 1;
} else {
left = p + 1;
}
}
return -1;
}
int partition(int[] nums, int left, int right) {
int pivot = nums[left];
int i = left + 1, j = right;
while (i <= j) {
while (i < right && nums[i] <= pivot) {
i++;
}
while (j > left && nums[j] >= pivot) {
j--;
}
if (i >= j) {
break;
}
swap(nums, i, j);
}
swap(nums, left, j);
return j;
}
void shuffle(int[] nums) {
int len = nums.length;
Random random = new Random();
for (int i = 0; i < len; i++) {
int j = i + random.nextInt(len - i);
swap(nums, i, j);
}
}
void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
//leetcode submit region end(Prohibit modification and deletion)