leetcode 215. Kth Largest Element in an Array 數組中的第K大的元素

https://leetcode.com/problems/kth-largest-element-in-an-array/

解法一:將數組看爲沒有調整到位的最大堆,由於堆是完全二叉樹,因此根節點與子節點的下標存在對應關係。

每次從堆中取出最大值,將其放至根節點,再與最後一個節點互換位置,然後將其從堆刪除。

參考視頻:https://www.bilibili.com/video/av47196993?from=search&seid=796459169887290526

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        int tmp;
        for(int i=0;i<k;i++){
            tmp = heapify(nums);
        }
        return tmp;
    }
    
    void swap(vector<int>& a, int i, int j){
        int tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
    }
    int heapify(vector<int>& a){//每次找出堆中最大值,將其移動至根節點,與最後一個節點互換後,將最大值從堆中刪除
        int n = a.size();
        if(n==1) {
            int tmp = a[0];
            a.pop_back();
            return tmp;
        }
        int last = n-1;
        int parent;
        for(parent = (last-1)/2; parent>-1; parent--){
            int c1 = 2*parent+1;//堆是完全二叉樹,所以父節點與子節點的數組下標存在固定關係
            int c2 = 2*parent+2;
            int maxi = parent;
            if(c1<n && a[c1]>a[maxi])
                maxi = c1;
            if(c2<n && a[c2]>a[maxi])
                maxi = c2;
            if(parent!=maxi)
                swap(a, parent, maxi);
        }
        int result = a[0];
        a[0] = a[last];
        a.pop_back();
        return result;
    }
};

解法二:採用快排中的partition算法,每次將首個元素記爲p,將數組中大於p的放在它的左邊,小於等於p的放在它右邊。如果此時p的序號正好等於給定的k,則返回p;如果p的序號小於k,對p右側的部分遞歸調用;如果p的序號大於k,對p左側的部分遞歸調用。

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        int left = 0;
        int right = nums.size()-1;
        int tmp = partition(nums, left, right);
        while(true){
            if(tmp+1==k) return nums[tmp];
            else if(tmp+1<k)
                left = tmp+1;
            else
                right = tmp-1;
            tmp = partition(nums, left, right);
        }
    }
    
    int partition(vector<int>&a, int l, int r){
        int p = a[l];
        int i=l, j=r;
        while(i<j){
            while(i<j && a[j]<=p) j--;
            if(i<j)
                a[i++]=a[j];
            while(i<j && a[i]>=p) i++;
            if(i<j)
                a[j--]=a[i];
        }
        if(i==j) a[i]=p;
        return i;
    }
};

歡迎關注公衆號:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章