1. 程式人生 > >LeetCode刷題MEDIM篇Kth Largest Element in an Array

LeetCode刷題MEDIM篇Kth Largest Element in an Array

題目

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.

Example 1:

Input: [3,2,1,5,6,4] and k = 2
Output: 5

Example 2:

Input: [3,2,3,1,2,4,5,5,6] and k = 4
Output: 4

十分鐘嘗試

以前做過一個類似題目,是求最大的k個數,其實是一樣的,這個題目是求第k大的數字。我當時那個題目也就是轉化為這個題目解決的。寫完了發現有個問題,我求的是第k大的數,是從小開始的,而題目的第k大,是從最大數字開始數的。比如

1 2 3 6 9,這個陣列,第2大的數字是6,而我的演算法是2. 稍微改動一下就可以。在分割槽的時候,大的放在右邊,小的放在左邊就可以了。程式碼如下:

class Solution {
    public int findKthLargest(int[] nums, int k) {
        k=nums.length-k+1;
        shuffle(nums);
        int res=quickSelect(nums,0,nums.length-1,k); 
        return res;
        
    }
    
    private void shuffle(int a[]) {
        final Random random = new Random();
        for(int index = 0; index < a.length; index++) {
            final int r = random.nextInt(a.length-index)+index;
            swap(a, index, r);
        }
    }
    private int quickSelect(int[] nums,int low,int high,int k){
        if (low > high) {
            return 0;
        }
        int i = low, j = high;
        while (i < j) {
            while (i < j && nums[j] >= nums[low]) {
                j --;
            }
            while (i < j && nums[i] <= nums[low]) {
                i ++;
            }
            swap(nums, i, j);
        }
        swap(nums, low, i);
        if(k == i - low + 1) {
            return nums[i];
        }
        else if(k < i - low + 1) {
            return quickSelect(nums, low, i - 1, k);
        }
        else {
            return quickSelect(nums, i + 1, high, k - (i - low + 1));
        }
        
    }
    
    private static void swap(int[] number, int i, int j) {
        int t;
        t = number[i];
        number[i] = number[j];
        number[j] = t;
    }


    
}

程式碼利用了選擇排序,基於快速排序的思想,基本程式碼一樣,只是選擇了在哪個區間進行排序。除錯過程中出現了問題,邏輯怎麼感覺沒問題,結果就是不對,原來引數順序寫的不一致,一定要注意引數順序一致:

quickSelect(nums, low, i - 1, k);