Leetcode215. 数组中的第K个最大元素 -hot100-面试必考精华版

题目:


代码(2023年10月27日首刷看解析):

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        return quickselect(nums,k);
    }

    int quickselect(vector<int>& nums,int k){
        vector<int> big,equel,small;
        int pivot = nums[rand()%nums.size()];
        for(auto num:nums){
            if(num>pivot){
                big.push_back(num);
            }else if(num<pivot){
                small.push_back(num);
            }else{
                equel.push_back(num);
            }
        }
        if(k<=big.size()){
            return quickselect(big,k);
        }
        else if(nums.size()-small.size()<k){
            return quickselect(small,k-(nums.size()-small.size()));
        }
        return pivot;
    }
};

        时间复杂度为O(N)


代码(二刷自解 超时 2024年3月9日)

struct MyListNode{
    int val;
    MyListNode* prev;
    MyListNode* next;
    MyListNode(int a) : val(a), prev(nullptr), next(nullptr) {}
};
class myQueue{
private:
    MyListNode* dummyHead = new MyListNode(INT_MIN);
    const int n;
    int count = 0;
    void push(int val, MyListNode* node) {
        MyListNode* newnode = new MyListNode(val);
        newnode->prev = node->prev;
        newnode->next = node;
        node->prev->next = newnode;
        node->prev = newnode;
    }
public:
    myQueue(int maxnum) : n (maxnum){
        dummyHead->next = dummyHead;
        dummyHead->prev = dummyHead;
    }
    void insert(int val) {
        MyListNode* cur = dummyHead->next;
        while (val < cur->val) {
            cur = cur->next;
        }
        push(val, cur);
        count++;
        if (count > n) {
            cur = dummyHead->prev;
            cur->prev->next = cur->next;
            cur->next->prev = cur->prev;
            cur->prev = nullptr;
            cur->next =nullptr;
            delete cur;
        }
    }
    int showLast() {
        return dummyHead->prev->val;
    }
};

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        myQueue q(k);
        for (int i = 0; i < nums.size(); ++i) {
            q.insert(nums[i]);
        }
        return q.showLast();
    }
};

代码(二刷看解析 构建大根堆 2024年3月9日)

class Solution {
public:
    void  maxHeapify(vector<int>& nums, int i, int heapSize) {
        int left = i * 2 + 1;
        int right = i * 2 + 2;
        int largest = i;

        if (left < heapSize && nums[left] > nums[largest]) {
            largest = left;
        }
        if (right < heapSize && nums[right] > nums[largest]) {
            largest = right;
        }

        if (largest != i) {
            swap(nums[largest], nums[i]);
            maxHeapify(nums, largest, heapSize);
        }
    }
    void buildmaxHeap(vector<int>& nums) {
        int heapSize = nums.size();
        for (int i = heapSize / 2 - 1; i >= 0; --i) {
            maxHeapify(nums, i, heapSize);
        }
    }
    int findKthLargest(vector<int>& nums, int k) {
        buildmaxHeap(nums);//大根堆排序
        int heapSize = nums.size();
        //每次将最大的数和队尾的数互换,并将heapSize-1
        for (int i = 0; i < k - 1; ++i) {
            swap(nums[0], nums[heapSize - 1]);
            --heapSize;
            maxHeapify(nums, 0, heapSize);
        }
        return nums[0];
    }
};


代码(三刷自解 debug on GPT 2024年3月31日)

我真破防了,heapifyDown的时候没传入引用,我一直不知道错在哪

class Solution {
public:
    // 小值下滤
    void heapifyDown(vector<int>& nums, int root, int heapSize) {
        int leftchild = root * 2 + 1;
        int rightchild = root * 2 + 2;
        int largest = root;

        if (leftchild < heapSize && nums[leftchild] > nums[largest]) {
            largest = leftchild;
        }
        if (rightchild < heapSize && nums[rightchild] > nums[largest]) {
            largest = rightchild;
        }
        
        if (largest != root) {
            swap(nums[root], nums[largest]);
            heapifyDown(nums, largest, heapSize);
        }
    }

    void make_heap(vector<int>& nums) {
        int heapSize = nums.size();
        for (int i = heapSize / 2 - 1; i >= 0; --i) {
            heapifyDown(nums, i, heapSize);
        }
    }

    int findKthLargest(vector<int>& nums, int k) {
        int heapSize = nums.size();
        make_heap(nums);
        for (int i = 0; i < k - 1; ++i) {
            swap(nums[0], nums[heapSize - 1]);
            --heapSize;
            heapifyDown(nums, 0, heapSize);
        }
        return nums[0];
    }
};

代码(四刷看解析 2024年7月26日)

class Solution {
    // 采用数据结构大跟堆,可以使用内置priority_queue
    // 自建大根堆:(完全二叉树,且父节点是最大的树)
    // 大跟堆可以抽象为树结构,树结构与数组下标映射关系知识点:左孩子index = 2 *
    // 父节点index + 1 右孩子index = 2 * 父节点index + 2,父节点 = (子节点 + 1) / 2 - 1
private:
    void maxHeapify(vector<int>& nums, int i, int heapSize) {
        int left = i * 2 + 1;
        int right = i * 2 + 2;
        int largest = i;

        // 找出局部二叉树三个节点最大的,放在父节点位置
        if (left < heapSize && nums[left] > nums[largest]) {
            largest = left;
        }
        if (right < heapSize && nums[right] > nums[largest]) {
            largest = right;
        }

        if (largest != i) {
            swap(nums[i], nums[largest]);
            // 递归上率
            maxHeapify(nums, largest, heapSize);
        }
    }

    void buildMaxHeap(vector<int>& nums) {
        // 构建大跟堆,只要把完全二叉树的倒数第二层以上的节点反向做一次节点上率即可
        for (int i = nums.size() / 2 - 1; i >= 0; i--) {
            maxHeapify(nums, i, nums.size());
        }
    }

public:
    int findKthLargest(vector<int>& nums, int k) {
        int heapSize = nums.size();
        buildMaxHeap(nums);
        for (int i = 0; i < k - 1; i++) {
            swap(nums[0], nums[heapSize - 1]);
            --heapSize;
            maxHeapify(nums, 0, heapSize);
        }
        return nums[0];
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值