1. 程式人生 > 實用技巧 >215. 陣列中的第K個最大元素

215. 陣列中的第K個最大元素

傳送門

程式碼

class Solution {
    public int findKthLargest(int[] nums, int k) {
        return quickSelect(nums,0,nums.length - 1,nums.length - k);
    }
    public int quickSelect(int[] a,int l,int r,int k) {
        if(l >= r) return a[l];
        int base = a[l + r >> 1];
        int i = l - 1,j = r + 1;
        while(i < j) {
            do i ++;while(a[i] < base);
            do j --;while(a[j] > base);
            if(i < j) swap(a,i,j);
        }
        if(k <= j) return quickSelect(a,l,j,k);
        else return quickSelect(a,j + 1,r,k);
    }
    public void swap(int[] a,int l,int r) {
        int t = a[l];
        a[l] = a[r];
        a[r] = t;
    }
}

思路

快速選擇演算法
時間複雜度 \(O(n)\)
參考快排的思路,但是每次只選擇一邊進行遞迴,不會把兩邊都遞迴
題目要求,第 k 大,也就是把陣列排序後(下標從 0 開始),第 n - k 小的數
每次直接把陣列以 base 為中心(這個 base 可以用 random 來取,可以防止被卡)切分成兩半
然後把整個陣列重新整理,撥開到兩邊,那麼這樣的話 base 所在的位置,就一定是排好序後,它下標的位置
最後 i j 退出迴圈的時候,一定在 base 的分界線處
所以,如果要求的下標 k 在左邊,就繼續遞迴左邊\([l,j]\),否則就遞迴右邊\([j + 1,r]\)
不斷夾逼,就會找到在下標為 k 的數