Leetcode Hot 100
- 一级目录
- 1.每日温度
- 堆
- 1.数组中的第K个最大元素
- 知识点:排序复杂度
- 知识点:堆的实现
- 2.前 K 个高频元素
- 知识点:优先队列
一级目录
1.每日温度
每日温度
思路是维护一个递减栈,存储的是当前元素的位置。
- 遍历整个数组,如果栈不空,且当前数字大于栈顶元素,那么需要pop出栈顶元素,由于当前数字大于栈顶元素的数字,而且一定是第一个大于栈顶元素的数,直接求出下标差就是二者的距离。
- 继续看新的栈顶元素,重复步骤一,直到当前数字小于等于栈顶元素停止,然后将数字入栈,这样就可以一直保持递减栈,且每个数字和第一个大于它的数的距离也可以算出来。
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 个高频元素
- 将数组放入unorderd_map<int, int> mp中,记录各元素对应出现的次数
- 将mp中的次数堆排,按照大根堆排序
- 最终将前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;}};