1. 程式人生 > >LeetCode 215. 陣列中的第K個最大元素 Kth Largest Element in an Array

LeetCode 215. 陣列中的第K個最大元素 Kth Largest Element in an Array

題目描述:就是在陣列中找到第k大的數

(1)第一種方法就是利用sort函式排序

時間複雜度 O(NlogN),空間複雜度 O(1)

public int findKthLargest(int[] nums, int k) {
    Arrays.sort(nums);
    return nums[nums.length - k];
}

(2)第二種方法是維護一個K大小的小根堆

這樣就可以始終保證K大小的小根堆中,堆頂是最小值,我們最後返回這個堆頂就可以了

其中使用的是優先順序佇列,關於優先順序佇列的介紹和怎麼表示一個堆以及怎麼插入和刪除調整一個堆,在下面連線中

https://www.cnblogs.com/Elliott-Su-Faith-change-our-life/p/7472265.html

程式碼

class Solution {
    public int findKthLargest(int[] nums, int k) {
         PriorityQueue <Integer> pq= new PriorityQueue<>();//java預設是一個小根堆
        for(int val:nums){
            pq.add(val);
            if(pq.size()>k){
                pq.poll();
            }
        }
        return pq.peek();
    }
}

(3)第三種方法是快速選擇 時間複雜度 O(N),空間複雜度 O(1)

這種方法是複製的別人的程式碼,並沒有仔細看

class Solution {
    public int findKthLargest(int[] nums, int k) {
        int begin=0;
        int end=nums.length-1;
         k=nums.length+1-k;
         while(begin<end){
            int pos=partition(nums,begin,end);
            if(pos==k-1) break;
            else if(pos<k-1) begin=pos+1;
            else end=pos-1;
        }
        return nums[k-1];
    }
    public int partition(int[]nums,int l,int r){
          int less=l-1;//小於區的下標
          int  more=r;//大於區的下標,預設以最後一個下標的數作為劃分值
          while(l<more){
              if(nums[l]<nums[r])
                 swap(nums,++less,l++);
              else if  (nums[l]>nums[r]) 
                 swap(nums,--more,l);
              else l++;
          }
          swap(nums,more,r);
          return less+1;//小於區位置+1可以得到劃分的這個數的下標
      }
    private void swap(int[] a, int i, int j) {
          int t = a[i];
          a[i] = a[j];
          a[j] = t;
    }
}