快排
选一个基数,使基数左边的都小于它,右边的都大于它,然后以基数为分界点对左右两边区间进行同样的操作
class Solution {
public int[] sortArray(int[] nums) {
int n = nums.length;
quickSort(nums,0,n-1);
return nums;
}
public void quickSort(int[] nums, int left , int right){
if(right<=left){
return ;
}
int l = left;
int r = right;
int tmp = nums[l];
while(l<r){
//从右边
while(l<r && nums[r]>=tmp){
r--;
}
if(l<r){
nums[l] = nums[r];
}
//从左边
while(l<r && nums[l]<tmp){
l++;
}
if(l<r){
nums[r] = nums[l];
}
nums[l] = tmp;
}
quickSort(nums,left,l-1);
quickSort(nums,l+1,right);
}
}
TopK问题
topk问题就是从一堆数据中找到前k大的数
我们可以维护一个大小为k的小顶堆,依次将数据放入堆中,堆满了,只用将数据和堆顶比较 如果当前元素大于堆顶元素就把堆顶元素抛弃,将当前元素插入堆中。
可以用PriorityQueue实现
使用堆解决
class Solution {
public int[] topK(int[] nums, int k) {
int[] ans = new int[k];
if(k==0||k>nums.length){
return ans;
}
Queue<Integer> queue = new PriorityQueue<Integer>();
for(int num:nums){
if(queue.size()<k){//堆没满直接把元素加进去
queue.add(num);
}
else if(queue.peek()<num){ //堆顶元素小于当前元素
queue.poll();//移除堆顶元素
queue.add(num);
}
}
for(int i=0;i<k;i++){
ans[i] = queue.poll();
}
return ans;
}
}
使用快排
快排的基数的左边是小于基数的,现在要找topk 我就只用找到基数的位置是k的时候即可,如果基数位置是小于k的那我就只用排基数右边
class Solution {
public int findKthLargest(int[] nums, int k) {
quickSortTopK(nums,0,nums.length-1,k); //将数组用快排对前k个元素进行排序
return nums[nums.length-k];
}
public void quickSortTopK(int[] nums,int left, int right,int k){
int l = left;
int r = right;
int tmp = nums[l];//基数
if(right<left ){
return ;
}
while(l<r){
//从右边
while(l<r&&nums[r]>=tmp){
r--;
}
if(l<r){
nums[l] = nums[r];
}
//从左边
while(l<r&&nums[l]<tmp){
l++;
}
if(l<r){
nums[r] = nums[l];
}
System.out.println('1');
nums[l] = tmp;
}
if(l==nums.length-k){
return ;
}
else if(l>nums.length-k){
quickSortTopK(nums,left,l-1,k);
}
else{
quickSortTopK(nums,l+1,right,k);
}
}
}