215. 数组中的第K个最大元素

该博客讨论了如何在未排序的数组中找到第K个最大的元素,提供了三种不同的解决方案:通过排序、使用快速排序的变体以及利用堆数据结构。其中,堆排序的方法分为直接堆排序和维护一个小顶堆来逐步找到第K大元素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题
在未排序的数组中找到第 k 个最大的元素
例子
在这里插入图片描述
思路
第k大,即下标为nums.length-k【第一大为len-1】

  • 暴力:先排序,然后返回nums.length-k下标
  • 使用快排,如果pivot_index是len-k的话就停止
  • 使用堆。
    1:堆排序,从第1大开始,找到第k大,就停止
    2:小顶堆(维持k个结点),然后不断把数组中的数字取出,如果大于最小的,替换掉最小的,最终小顶堆的根节点就是k大

代码

//暴力:
Arrays.sort(nums);
return nums[nums.length-k];
//快排
    public int findKthLargest(int[] nums, int k) {
        //第k大的坐标为nums.length-k
        int low = 0, high=nums.length-1;
        
        while (low<high){
            int pivot_index = partition(nums,low,high);
            if (pivot_index==nums.length-k) break;
            if (pivot_index<nums.length-k) low=pivot_index+1;
            if (pivot_index>nums.length-k) high = pivot_index-1;
        }
        return nums[nums.length-k];
    }
    public void quick_sort(int[] nums,int low, int high,int k) {
        if (low>=high) return ;
        int pivot_index = partition(nums,low,high);
        if (pivot_index==nums.length-k) {
            return;
        }
        quick_sort(nums,low,pivot_index-1,k);
        quick_sort(nums,pivot_index+1,high,k);
      
        
    }
    public int partition(int[] nums, int low, int high) {
        int pivot_index = low;
        int pivot=nums[low];
        while (low<high) {
            while (low<high && nums[high]>=pivot) high--;
            while (low<high && nums[low]<=pivot) low++;
            if (low<high) {
                int temp = nums[high];
                nums[high]=nums[low];
                nums[low]=temp;
            }
        }
        if (pivot_index!=high) {
            int temp = pivot;
            nums[pivot_index]=nums[high];
            nums[high]=temp;
        }
        return high;
    }
}
//堆
    public int findKthLargest(int[] nums, int k) {
        heap_sort(nums,k);
        return nums[nums.length-k];
        
    }
    
    public void heapify(int[] nums, int n, int i) {
        
        if (2*i+1>n-1) return ;
        
        int L = 2*i+1, R = 2*i+2;
        
        int max_index = i;
        max_index = nums[L]<=nums[max_index]?max_index:L;
        if (R<=n-1) {
            max_index = nums[R]<=nums[max_index]?max_index:R;
        }
        
        if (max_index!=i) {
            int temp = nums[max_index];
            nums[max_index]=nums[i];
            nums[i]=temp;
            
            heapify(nums,n,max_index);
        }
    }
    
    public void build_heapify(int[] nums) {
        int last_index = nums.length-1;
        int last_father = (last_index-1)/2;
        
        for (int i=last_father; i>=0; i--) {
            heapify(nums,nums.length,i);
            
        }
        
    }
     public void heap_sort(int[] nums,int k) {
         build_heapify(nums);

         for(int i=nums.length-1; i>=0; i--) {
             
             int temp = nums[0];

             nums[0]=nums[i];
             nums[i]=temp;
             System.out.println(Arrays.toString(nums));
             if (k==nums.length-i) return;
             
             heapify(nums,i,0);
         }
     }
}
//小顶堆
    public int findKthLargest(int[] nums, int k) {
        PriorityQueue<Integer> pq = new PriorityQueue<>();
        for (int i=0; i<nums.length; i++) {
            if (pq.size()<k) {
                pq.offer(nums[i]);
            }else {
                if (nums[i]>pq.peek()) {
                    pq.poll();//将最小的拉出
                    pq.offer(nums[i]);
                }
            }
            
        }
        
        return pq.peek();
        
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值