215. 陣列中的第K個最大元素
阿新 • • 發佈:2020-12-13
傳送門
程式碼
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 的數