Leetcode 3.26

一级目录

1.每日温度

每日温度
思路是维护一个递减栈,存储的是当前元素的位置。

  1. 遍历整个数组,如果栈不空,且当前数字大于栈顶元素,那么需要pop出栈顶元素,由于当前数字大于栈顶元素的数字,而且一定是第一个大于栈顶元素的数,直接求出下标差就是二者的距离。
  2. 继续看新的栈顶元素,重复步骤一,直到当前数字小于等于栈顶元素停止,然后将数字入栈,这样就可以一直保持递减栈,且每个数字和第一个大于它的数的距离也可以算出来。

step 1:
在这里插入图片描述
step 2:
在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        stack<int> stk;
        //都置为0,处理边界情况
        vector<int> ans(temperatures.size(), 0);
        for (int i = 0; i < temperatures.size(); i++) {
            if (stk.empty()) {
                //为空则直接入栈,存储的是元素的位置
                stk.push(i);
            } else {
                //比栈顶元素大
                while (!stk.empty() && temperatures[i] > temperatures[stk.top()]) {
                    //栈顶元素出栈
                    auto site = stk.top();
                    stk.pop();
                    //记录差值
                    ans[site] = i - site;
                }
                //当前元素入栈
                stk.push(i);
            }
        }
        return ans;
    }
};

1.数组中的第K个最大元素

数组中的第K个最大元素
第K个最大元素用堆做比较容易,可以维护一个只有K个元素的大根堆,如果元素个数超过K则pop,也就是将堆顶大元素删除,那么当前堆就是一个以第K大元素为堆顶的大根堆。堆可以用priority_queue实现。

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        priority_queue<int, vector<int>, greater<int>> pq;
        for (auto &n : nums) {
            pq.push(n);
            while (pq.size() > k) {
                pq.pop();
            }
        }
        return pq.top();
    }
};

知识点:排序复杂度

各种排序的复杂度需要烂熟于心:
在这里插入图片描述

知识点:堆的实现

当然在面试中,面试官更倾向于让更面试者自己实现一个堆。所以建议掌握这里大根堆的实现方法,在这道题中尤其要搞懂「建堆」、「调整」和「删除」的过程。

class Solution {
public:
    void maxHeapify(vector<int>& a, int i, int heapSize) {
        int l = i * 2 + 1, r = i * 2 + 2, largest = i;
        if (l < heapSize && a[l] > a[largest]) {
            largest = l;
        } 
        if (r < heapSize && a[r] > a[largest]) {
            largest = r;
        }
        if (largest != i) {
            swap(a[i], a[largest]);
            maxHeapify(a, largest, heapSize);
        }
    }

    void buildMaxHeap(vector<int>& a, int heapSize) {
        for (int i = heapSize / 2; i >= 0; --i) {
            maxHeapify(a, i, heapSize);
        } 
    }

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

2.前 K 个高频元素

前 K 个高频元素

  1. 将数组放入unorderd_map<int, int> mp中,记录各元素对应出现的次数
  2. 将mp中的次数堆排,按照大根堆排序
  3. 最终将前K个元素放入vector中

知识点:优先队列

本题难点在于priority_queue的相关知识,如何自定义比较方式等。比如本题的数据类型并不是基本数据类型,而是pair<int, int>,所以需要自定义比较方式

        struct myComparision {
            bool operator() (pair<int, int> &p1, pair<int, int> &p2) {
                return p1.second < p2.second;
            }
        };

代码实现:

class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int, int>mp;
        vector<int> ans;
        for (auto& n: nums) {
            mp[n]++;
        }
        //用仿函数自定义比较方式,大根堆是小于
        struct myComparision {
            bool operator() (pair<int, int> &p1, pair<int, int> &p2) {
                return p1.second < p2.second;
            }
        };
        priority_queue <pair<int, int>, vector<pair<int, int>>, myComparision> pq;
        for (auto &a: mp) {
            pq.push(a);
        }
        while (k--) {
            ans.push_back(pq.top().first);
            pq.pop();
        }
        return ans;
    }

};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值