栈实现队列
优化点:不用每次都将第一个栈倒到第二个,然后倒回去,而是第二个作为队头的替代,只要第二个栈有元素,那么pop就pop第二个栈的,不然就把第一个栈全倒过去
获取队头也同样,直接从第二个栈获取就行
/** Removes the element from in front of queue and returns that element. */
int pop() {
// 只有当stOut为空的时候,再从stIn里导入数据(导入stIn全部数据)
if (stOut.empty()) {
// 从stIn导入数据直到stIn为空
while(!stIn.empty()) {
stOut.push(stIn.top());
stIn.pop();
}
}
int result = stOut.top();
stOut.pop();
return result;
}
/** Get the front element. */
int peek() {
int res = this->pop(); // 直接使用已有的pop函数
stOut.push(res); // 因为pop函数弹出了元素res,所以再添加回去
return res;
}
队列实现栈
优化:只使用一个队列,将队列长度(n)的前n-1队头元素重新放到队尾,此时剩下的最后一个元素就是栈顶元素
int pop() {
int size = que.size();
size--;
while (size--) { // 将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部
que.push(que.front());
que.pop();
}
int result = que.front(); // 此时弹出的元素顺序就是栈的顺序了
que.pop();
return result;
}
int top(){
int size = que.size();
size--;
while (size--){
// 将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部
que.push(que.front());
que.pop();
}
int result = que.front(); // 此时获得的元素就是栈顶的元素了
que.push(que.front()); // 将获取完的元素也重新添加到队列尾部,保证数据结构没有变化
que.pop();
return result;
}
括号匹配
栈内保存的是左括号,匹配到了右括号就pop(在遍历过程中pop,不能先遍历一遍都入栈再pop,不能分两次处理,这样顺序不对)
删除字符串中的所有相邻重复项
string可以字符串拼接,不需要提前申请长度
string result = "";
result += st.top();
逆波兰表达式
原理:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中
向零截断 : c++的默认除法截断方式
获取滑动窗口最大值
滑动的本质:上一个元素出队,下一个元素入队
先让一组窗口入队,将最大值获取,然后遍历数组,使用滑动窗口
单调队列:
- push操作:如果队列非空,前一个元素比当前元素小,那么pop上一个元素,直到当前元素小于前一个元素,再入队
- pop:
pop其实是在将上一个滑动窗口和当前的非重叠元素踢出队列,
如果当前元素和队首相同(也就是说是上一个窗口的最大值),才需要pop,不然队首元素一定是当前窗口和上一个窗口重叠部分的最大值,这个元素被弹出会影响本次窗口的判断 - front:正常返回队首元素
前k个高频元素
map没什么可说的
priority_queue的语法:
std::priority_queue 的第三个模板参数需要一个可调用对象类型,这个可调用对象用于定义优先队列中元素的比较规则。 可传入的参数:
- 定义好的仿函数:priority_queue<std::pair<int, int>, vector, greater<std::pair<int, int>>> pq;
- 使用函数对象(仿函数)
函数对象是一个重载了 () 运算符的类或结构体的实例,它可以像函数一样被调用。
class mycomparison {
public:
bool operator()(const pair<int, int>& lhs, const pair<int, int>& rhs) {
return lhs.second > rhs.second;
}
};
priority_queue<pair<int, int>, vector<pair<int, int>>, mycomparison> pri_que;
- 使用lambda表达式,然后包装成一个函数:
// 定义 lambda 表达式作为比较器
auto mycomparison = [](const std::pair<int, int>& a, const std::pair<int, int>& b) {
return a.second > b.second;
};
// 使用 std::function 包装 lambda 表达式
std::priority_queue<std::pair<int, int>,
std::vector<std::pair<int, int>>,
std::function<bool(const std::pair<int, int>&, const std::pair<int, int>&)>> pri_que(mycomparison);
然后将构造好的queue,push元素,如果长度超过k,那么pop就可以了
最后将queue中的元素放入结果