215. Kth Largest Element in an Array

https://www.jianshu.com/p/b30955885e6d

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.

Approach 1: Priority Queue

class Solution {
    public int findKthLargest(int[] nums, int k) {
        PriorityQueue<Integer> minQ = new PriorityQueue<>(k);
        
        for(int i: nums) {
            if(minQ.size() < k) {
                minQ.add(i);
                continue;
            }
            
            if(i<=minQ.peek())
                continue;
            
            minQ.remove();
            minQ.add(i);
            
        }
        return minQ.peek();
    }
}

Runtime: 8 ms, faster than 46.78% of Java online submissions for Kth Largest Element in an Array.

Memory Usage: 46.2 MB, less than 5.18% of Java online submissions for Kth Largest Element in an Array.

Approach 2: Quick Select

1. Swap low and high element

class Solution {
    public int findKthLargest(int[] nums, int k) {
        int index = findKthLargest(nums, 0, nums.length-1, k);
        return nums[index];
    }
    
    int findKthLargest(int[] nums, int start, int end, int k) {
        int pivot = nums[start];
        int i=start+1;
        int j=end;
        int temp;
        while(i<=j){
           while(i<=j) {
                if(nums[i] >= pivot) {
                    i++;
                }
                else {
                    break;
                }
            }
            
            while(i<=j) {
                if(nums[j] <= pivot) {
                    j--;
                }
                else {
                    break;
                }
            }
            
            if( i < j) {
                temp = nums[i] ;
                nums[i++] = nums[j];
                nums[j--] = temp;
            }
        }
        
        nums[start] = nums[j];
        nums[j] = pivot;
        int count = j - start + 1;

        if(count == k) return j;
        if(count < k) return findKthLargest(nums, j+1, end, k - count); 
        return findKthLargest(nums, start, j-1, k); 
    }
    
}

Runtime: 33 ms, faster than 16.55% of Java online submissions for Kth Largest Element in an Array.

Memory Usage: 47.7 MB, less than 5.18% of Java online submissions for Kth Largest Element in an Array.

Improve performance (16.55% -> 99.39%😄)

shuttle pivot

        //int mid = start+ (end -start) /2;
        int mid =  (int) ((Math.random() * (end - start)) + start);
        
        temp = nums[mid] ;
        nums[mid] = nums[start];
        nums[start] = temp;

Runtime: 1 ms, faster than 99.39% of Java online submissions for Kth Largest Element in an Array.

Memory Usage: 46.9 MB, less than 5.18% of Java online submissions for Kth Largest Element in an Array.

  class Solution {
      public int findKthLargest(int[] nums, int k) {
          int index = findKthLargest(nums, 0, nums.length-1, k);
          return nums[index];
      }
      
      int findKthLargest(int[] nums, int start, int end, int k) {
          int temp;
          
          //int mid = start+ (end -start) /2;
          int mid =  (int) ((Math.random() * (end - start)) + start);
          
          temp = nums[mid] ;
          nums[mid] = nums[start];
          nums[start] = temp;
          
          int pivot = nums[start];
          int i=start+1;
          int j=end;
         
          while(i<=j){
             while(i<=j) {
                  if(nums[i] >= pivot) {
                      i++;
                  }
                  else {
                      break;
                  }
              }
              
              while(i<=j) {
                  if(nums[j] <= pivot) {
                      j--;
                  }
                  else {
                      break;
                  }
              }
              
              if( i < j) {
                  temp = nums[i] ;
                  nums[i++] = nums[j];
                  nums[j--] = temp;
              }
          }
          
          nums[start] = nums[j];
          nums[j] = pivot;
          int count = j - start + 1;
  
          if(count == k) return j;
          if(count < k) return findKthLargest(nums, j+1, end, k - count); 
          return findKthLargest(nums, start, j-1, k); 
      }
      
  }

2. Repeatly search high and low element respectively

class Solution {
    public int findKthLargest(int[] nums, int k) {
        int index = findKthLargest(nums, 0, nums.length-1, k);
        return nums[index];
    }
    
    int findKthLargest(int[] nums, int start, int end, int k) {
        int pivot = nums[start];
        int i=start;
        int j=end;
        while(i<j){
            while(i<j) {
                if(nums[j] <= pivot) {
                    j--;
                }
                else {
                    nums[i++] = nums[j];
                    break;
                }
            }
            
            while(i<j) {
                if(nums[i] >= pivot) {
                    i++;
                }
                else {
                    nums[j--] = nums[i];
                    break;
                }
            }
        }
        
        nums[i] = pivot;
        int count = i - start + 1;

        if(count == k) return i;
        if(count < k) return findKthLargest(nums, i+1, end, k - count); 
        return findKthLargest(nums, start, i-1, k); 
    }
    
}

Runtime: 43 ms, faster than 6.17% of Java online submissions for Kth Largest Element in an Array.

Memory Usage: 47.1 MB, less than 5.18% of Java online submissions for Kth Largest Element in an Array.

Improve performance

shuttle pivot as above

發佈了208 篇原創文章 · 獲贊 14 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章