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;
    }
};

欢迎关注公众号:

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