【算法】排序问题整理

快排

选一个基数,使基数左边的都小于它,右边的都大于它,然后以基数为分界点对左右两边区间进行同样的操作

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的那我就只用排基数右边

215. 数组中的第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);
        }
        
        
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值