📝前言说明:
本专栏主要记录本人的基础算法学习以及刷题记录,使用语言为C++。
每道题我会给出LeetCode上的题号(如果有题号),题目,以及最后通过的代码。没有题号的题目大多来自牛客网。对于题目的讲解,主要是个人见解,如有不正确,欢迎指正,一起进步!
🎬个人简介:努力学习ing
📋本专栏:C++刷题专栏
📋其他专栏:C++学习笔记,C语言入门基础,python入门基础,python刷题专栏
🎀CSDN主页 愚润泽
题目
- 20. 有效的括号
- 225. 用队列实现栈
- 232. 用栈实现队列
- 622. 设计循环队列
- 面试题03.05. 栈排序
20. 有效的括号
经典的括号匹配题:利用栈。遇到左括号:入栈,遇到右括号:出栈
不过写代码时要注意:因为我们要让'(' 匹配 ')'
,所以遇到左括号时,直接将它对应的右括号入栈,后续可以直接字符比较判断。
class Solution {
public:bool isValid(string s) {stack<char> st;for(auto ch : s){if(ch == '('){st.push(')'); // 需要匹配的}else if (ch == '['){st.push(']');}else if (ch == '{'){st.push('}');}else{if( st.empty() || ch != st.top()){ // 这里要先判断栈是否为空return false;}st.pop();}}return st.empty();}
};
225. 用队列实现栈
首先我们要了解栈的特点:先进后出,队列的特点:先进先出
因此,这道题的难点在于:如何让新入队的元素处于队头?
这道题给了我们两个队列,如果将一个队列当做主队列(即栈),另一个队列作为辅助队列,我们就可以利用辅助队列来改变新入队的元素的位置:
前提:每次操作前,辅助队列要为空。
思想:如果直接让新元素进主队列,那这个元素肯定是最后一个了,但是直接让新元素进辅助队列,那这个新元素就是辅助的第一个元素。所以我们先让新元素进入辅助队列,然后再把主队列(栈)里的元素依次出栈放入辅助队列,这样在辅助队列里新元素第一个出队列,而其他元素的出队列顺序与原来的主队列(栈)保持一致。这时候我们再交换辅助队列和主队列的身份。
class MyStack {
public:queue<int> queue1; queue<int> queue2; MyStack() {}void push(int x) {queue2.push(x); // 把新元素放到辅助队列while(!queue1.empty()){queue2.push(queue1.front()); // 依次将栈的元素放入辅助队列queue1.pop();}swap(queue1, queue2);}int pop() {int r = queue1.front();queue1.pop();return r;}int top() {return queue1.front();}bool empty() {return queue1.empty();}
};/*** Your MyStack object will be instantiated and called as such:* MyStack* obj = new MyStack();* obj->push(x);* int param_2 = obj->pop();* int param_3 = obj->top();* bool param_4 = obj->empty();*/
232. 用栈实现队列
只需要让一个栈进,一个栈负责出就行了。当一个栈的元素全部倒入另一个栈,这时候元素的出入顺序就会完全改变一次。(为了节约时间,我们只在outStack
里面元素彻底为空且遇到出栈需求时,才将inStack
的数据倒入`outStack)
class MyQueue {
public:stack<int> inStack, outStack;void in_to_out(){ // 倒转while(!inStack.empty()){outStack.push(inStack.top());inStack.pop();}}MyQueue() {}void push(int x) {inStack.push(x);}int pop() {if(outStack.empty()){in_to_out();}int r = outStack.top();outStack.pop(); return r;}int peek() {if(outStack.empty()){in_to_out();}return outStack.top();}bool empty() {return inStack.empty() && outStack.empty();}
};/*** Your MyQueue object will be instantiated and called as such:* MyQueue* obj = new MyQueue();* obj->push(x);* int param_2 = obj->pop();* int param_3 = obj->peek();* bool param_4 = obj->empty();*/
622. 设计循环队列
下面解法以数组为例:
环形队列的关键在于:1,如何通过取模来达到走环的效果;2,如何判断队列满和空的情况。
对于循环:当一个数+1
时可能超出最大值,则需要%
来控制此数的大小任然在下标范围内;
对于判空:起始时front
指针和rear
指针都指向空;对于满,我们可以牺牲一个空间,即:当rear+1 == front
的时候为满(但注意rear + 1
要确保在数组下标内)。
下面做法以front
的后一位为第一个数据位为例:
class MyCircularQueue {
public:// 用数组来模拟循环队列,让front指向的位置为空,front下一个位置才有节点// front == rear时为空,当 rear + 1 == front 时为满 MyCircularQueue(int k) {capacity = k;front = rear = 0;que = vector<int> (k+1); // 比容量多开一个空间,则数组下标为[0, k](后续我们要让rear和front的下标在这个范围内,不然会越界)}bool enQueue(int value) {if(isFull()){return false;}rear = (rear + 1) % (capacity + 1); que[rear] = value;return true;}bool deQueue() {if(isEmpty()){return false;}front = (front + 1) % (capacity + 1);return true;}int Front() {if(isEmpty()){return -1;}return que[(front + 1) % (capacity + 1)];}int Rear() {if(isEmpty()){return -1;}return que[rear];}bool isEmpty() {return rear == front;}bool isFull() {return ((rear + 1) % (capacity + 1)) == front;}private:int front;int rear;int capacity;vector<int> que;
};/*** Your MyCircularQueue object will be instantiated and called as such:* MyCircularQueue* obj = new MyCircularQueue(k);* bool param_1 = obj->enQueue(value);* bool param_2 = obj->deQueue();* int param_3 = obj->Front();* int param_4 = obj->Rear();* bool param_5 = obj->isEmpty();* bool param_6 = obj->isFull();*/
面试题03.05. 栈排序
这道题的题目表述不清楚,看示例可以发现,实际上是往栈里面插入元素,要保证插入后的顺序从栈底到栈顶是从大到小的。
我们只需要将每次要插入的元素和栈中已经有的元素作比较,找到合适的位置插入。
如:栈顶元素为t
,要插入元素为val
,如果val < t
,就直接入栈,否则,先让t
进入辅助栈,重复此过程,直到找到合适的位置插入,插入完后,把st2
的元素倒回来。
class SortedStack {
public:SortedStack() {}void push(int val) {while( !st1.empty() && st1.top() < val){st2.push(st1.top()); // 把st1的元素暂存到st2st1.pop();}st1.push(val);// 把st2的元素倒回来while(!st2.empty()){st1.push(st2.top());st2.pop();}}void pop() {if(!st1.empty()){st1.pop();}}int peek() {if(!st1.empty()){return st1.top();}return -1;}bool isEmpty() {return st1.empty();}
private:stack<int> st1, st2;
};/*** Your SortedStack object will be instantiated and called as such:* SortedStack* obj = new SortedStack();* obj->push(val);* obj->pop();* int param_3 = obj->peek();* bool param_4 = obj->isEmpty();*/
🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!