一道算法題:第K大的數

給一個無序的包涵n個元素的數組,找出其中第k大的數(n > k)。
初看到這個題的時候,作為一個寫了一段時間java的人,立刻能想到的一種解法就是:

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

時間復雜度時NlgN, 空間復雜度時O(1).
看起來貌似不錯,但既然這道題目被廣泛地討論,就肯定還有其他解法,比如說:

class Solution {
    public int kthLargestElement(int k, int[] nums) {
        // write your code here
        PriorityQueue<Integer> pq = new PriorityQueue<>();
        for(int val : nums) {
            pq.add(val);
            if(pq.size() > k) {
                pq.poll();
            }
        }
        return pq.peek();
    }
};

當然建堆需要額外的空間,而且時間復雜度上并沒有多少提升,所以不能算什么優化。
更好的一種解法是利用快速排序的劃分思想,這種解法是一種O(n)的解法

class Solution {
    
    public int kthLargestElement(int k, int[] nums) {
        //打亂數組避免最壞情況
        shuffle(nums);
        k = nums.length - k;
        int lo = 0, hi = nums.length - 1;
        while(lo < hi){
            int j = partition(nums, lo, hi);
            if(j < k){
                lo = j + 1;
            }else if(j > k){
                hi = j - 1;
            }else{
                break;
            }
        }
        return nums[k];
    }
    
    private int partition(int[] nums, int lo, int hi){
        int i = lo;
        int j = hi + 1;
        while(true){
            while(i < hi && nums[++i] < nums[lo]);
            while(j > lo && nums[lo] < nums[--j]);
            if(j <= i) break;
            exch(nums, i, j);
        }
        exch(nums, lo, j);
        return j;
    }
    
    private void exch(int[] nums, int i, int j){
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
  
    private void shuffle(int a[]) {
        Random random = new Random();
        for(int ind = 1; ind < a.length; ind++) {
            int r = random.nextInt(ind + 1);
            exch(a, ind, r);
        }
    }
};
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1. 鏈表 鏈表是最基本的數據結構,面試官也常常用鏈表來考察面試者的基本能力,而且鏈表相關的操作相對而言比較簡單,...
    Mr希靈閱讀 1,463評論 0 20
  • 背景 一年多以前我在知乎上答了有關LeetCode的問題, 分享了一些自己做題目的經驗。 張土汪:刷leetcod...
    土汪閱讀 12,768評論 0 33
  • 詩情猶赴蓮花影,輕覓粉蛺蝶。 翩躚曼舞,幽芳欲醉,蕊瓣誠潔。 暇來恬靜,荷風日暖,架翅浮歇。 磐縈碧水,陶然入畫,...
    小薇_閱讀 337評論 11 14
  • 最早的時候,東山的公交車只有一路,就是1路車,1路車總站在東山百貨大樓門前。 每次站在1路車總站,我都會暈路,因為...
    夏愛東西閱讀 634評論 2 3
  • 科研|讀博的心得與體會
    123逍遙游閱讀 233評論 0 1