239. 滑动窗口最大值 (一刷至少需要理解思路)
维护单调队列
让front处一直是最大的,其次递减
单调队列是存储可能为最大值的元素
本题算比较有难度的,需要自己去构造单调队列,建议先看视频来理解。
题目链接/文章讲解/视频讲解:代码随想录
class Solution {
public:
deque<int> que;
void push(int k){
// cout<<k<<endl;
while(!que.empty()&&que.back()<k){
que.pop_back();
//cout<<que.front()<<"hahhaha"<<endl;
}
que.push_back(k);
}
void pop(int k){
if(!que.empty()&&que.front()==k){
que.pop_front();
}
}
int getMaxVal(){
return que.front();
}
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> results;
for(int i = 0;i<k;i++){
push(nums[i]);
}
for(int i = k; i<=nums.size()-1;i++){
results.push_back(getMaxVal());
//cout<<nums[i]<<endl;
push(nums[i]);
//cout<<nums[i-k]<<" ";
pop(nums[i-k]);
}
results.push_back(getMaxVal());
return results;
}
};
347.前 K 个高频元素 (一刷至少需要理解思路)
大/小顶堆的应用, 在C++中就是优先级队列
本题是 大数据中取前k值 的经典思路,了解想法之后,不算难。
题目链接/文章讲解/视频讲解:代码随想录
- 完全二叉树(Complete Binary Tree)是一种特殊的二叉树,它具有以下性质:
-
节点填充顺序:完全二叉树的节点是按照层序遍历的顺序从左到右填充的。也就是说,如果一个节点有子节点,那么这两个子节点必须在下一层的相同位置。
-
最后一层:在完全二叉树中,最后一层的节点可能会集中在左边,也就是说,最后一层的右边可能没有节点。但是,如果最后一层有节点,那么它们会从左到右填充,直到填满整层或者达到树的高度。
-
节点数量:完全二叉树的节点数量可以是任意的,但是它必须满足上述的填充规则
堆是一棵完全二叉树,树中每个结点的值都不小于(或不大于)其左右孩子的值。 如果父亲结点是大于等于左右孩子就是大顶堆,小于等于左右孩子就是小顶堆。
弹出操作在堆顶,所以维护小顶堆
学会了写比较器类(覆盖operator(),返回第一个元素是否排在第二个元素前的bool值)【要设置为public】
学会了priority queue的写法(元素类型,容器类型,比较函数)
class Solution {
public:
class mycomparison{
public:
bool operator()(const pair<int,int>&lhs, const pair<int,int> &rhs){
return lhs.second > rhs.second;
}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int,int> map;
for(int i = 0; i<nums.size();i++){
map[nums[i]]++;
}
priority_queue<pair<int,int>,vector<pair<int,int>>,mycomparison> pqueue;
for(unordered_map<int,int>::iterator it = map.begin();it!=map.end();it++){
pqueue.push(*it);
if(pqueue.size()>k){
pqueue.pop();
}
}
vector<int> result(k);
for(int i = k-1;i>=0;i--){
result[i] = pqueue.top().first;
pqueue.pop();
}
return result;
}
};
需要了解 二叉树的种类,存储方式,遍历方式 以及二叉树的定义
文章讲解:代码随想录
递归遍历
二叉树的三种递归遍历掌握其规律后,其实很简单
题目链接/文章讲解/视频讲解:代码随想录
144. 前序:递归函数+外部变量
class Solution {
public:
vector<int> results;
void traverse(TreeNode* root){
if(root == nullptr) return;
results.push_back(root->val);//调换位置就可以变成后序和中序
traverse(root->left);
traverse(root->right);
}
vector<int> preorderTraversal(TreeNode* root) {
if(root == nullptr) return results;
traverse(root);
return results;
}
};
迭代遍历 (基础不好的录友,迭代法可以放过)
题目链接/文章讲解/视频讲解:代码随想录
统一迭代 (基础不好的录友,迭代法可以放过)
这是统一迭代法的写法, 如果学有余力,可以掌握一下
题目链接/文章讲解:代码随想录