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