请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push
、pop
、peek
、empty
):
实现 MyQueue
类:
void push(int x)
将元素 x 推到队列的末尾int pop()
从队列的开头移除并返回元素int peek()
返回队列开头的元素boolean empty()
如果队列为空,返回 true
;否则,返回 false
说明:
push to top
, peek/pop from top
, size
, 和 is empty
操作是合法的。示例 1:
输入:
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]
解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false
需要了解一些c++中栈操作的语法:
在C++中,栈操作通常使用标准库中的std::stack
容器适配器。std::stack
基于其他容器(如std::deque
、std::list
或std::vector
)实现,默认使用std::deque
作为底层容器。
以下是std::stack
的基本操作语法:
#include
std::stack<int> myStack; // 声明一个存储int类型元素的栈
push
)myStack.push(10); // 将元素10压入栈顶
myStack.push(20); // 将元素20压入栈顶
top
)int topElement = myStack.top(); // 获取栈顶元素,但不移除它
pop
)myStack.pop(); // 移除栈顶元素
empty
)if (myStack.empty()) {
std::cout << "栈为空" << std::endl;
} else {
std::cout << "栈不为空" << std::endl;
}
size
)std::size_t stackSize = myStack.size(); // 获取栈中元素的数量
#include
#include
int main() {
std::stack<int> myStack;
// 压栈
myStack.push(10);
myStack.push(20);
myStack.push(30);
// 访问栈顶元素
std::cout << "栈顶元素: " << myStack.top() << std::endl;
// 弹栈
myStack.pop();
std::cout << "弹栈后的栈顶元素: " << myStack.top() << std::endl;
// 检查栈是否为空
if (myStack.empty()) {
std::cout << "栈为空" << std::endl;
} else {
std::cout << "栈不为空" << std::endl;
}
// 获取栈的大小
std::cout << "栈的大小: " << myStack.size() << std::endl;
return 0;
}
栈顶元素: 30
弹栈后的栈顶元素: 20
栈不为空
栈的大小: 2
std::stack
不支持直接遍历元素,因为它是基于LIFO(后进先出)原则设计的。std::vector
或std::deque
)来模拟栈的行为。通过这些操作,你可以在C++中轻松地使用栈数据结构。
class MyQueue {
public:
stack<int> Mystack1;
stack<int> Mystack2;
MyQueue() {
}
void push(int x) {
int tmp;
while(!Mystack2.empty()){
tmp=Mystack2.top();
Mystack2.pop();
Mystack1.push(tmp);
}
Mystack1.push(x);
}
int pop() {
int tmp;
while(!Mystack1.empty()){
tmp=Mystack1.top();
Mystack1.pop();
Mystack2.push(tmp);
}
tmp=Mystack2.top();
Mystack2.pop();
return tmp;
}
int peek() {
int tmp;
while(!Mystack1.empty()){
tmp=Mystack1.top();
Mystack1.pop();
Mystack2.push(tmp);
}
tmp=Mystack2.top();
return tmp;
}
bool empty() {
return Mystack1.empty()&&Mystack2.empty();
}
};
感觉效率很低
class MyQueue {
public:
stack<int> stIn;
stack<int> stOut;
/** Initialize your data structure here. */
MyQueue() {
}
/** Push element x to the back of queue. */
void push(int x) {
stIn.push(x);
}
/** 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;
}
/** Returns whether the queue is empty. */
bool empty() {
return stIn.empty() && stOut.empty();
}
};
这种做法更加巧妙,关键点在于只有当Mystack2用完时,再从Mystack1里面导入,节约了数据倒来倒去的时间。
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push
、top
、pop
和 empty
)。
实现 MyStack
类:
void push(int x)
将元素 x 压入栈顶。int pop()
移除并返回栈顶元素。int top()
返回栈顶元素。boolean empty()
如果栈是空的,返回 true
;否则,返回 false
。注意:
push to back
、peek/pop from front
、size
和 is empty
这些操作。class MyStack {
public:
queue<int> Myque;
int size;
MyStack() {
size=0;
}
void push(int x) {
Myque.push(x);
size++;
}
int pop() {
int tmp;
for(int i=0;i<size-1;i++){
tmp=Myque.front();
Myque.pop();
Myque.push(tmp);
}
tmp=Myque.front();
Myque.pop();
size--;
return tmp;
}
int top() {
int tmp;
for(int i=0;i<size;i++){
tmp=Myque.front();
Myque.pop();
Myque.push(tmp);
}
return tmp;
}
bool empty() {
return size==0;
}
};
复杂度有点高
和代码随想录思路一样的
给定一个只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串 s
,判断字符串是否有效。
有效字符串需满足:
示例 1:
**输入:**s = “()”
**输出:**true
示例 2:
**输入:**s = “()[]{}”
**输出:**true
示例 3:
**输入:**s = “(]”
**输出:**false
示例 4:
**输入:**s = “([])”
**输出:**true
提示:
1 <= s.length <= 104
s
仅由括号 '()[]{}'
组成我想用三个栈分别匹配三种括号,最后如果栈都为空则匹配成功
鉴于三种符合不能交叉,所以一个栈就行
class Solution {
public:
bool isValid(string s) {
stack<int> MyStack;
for(int i=0;i<s.size();i++){
switch (s[i])
{
case '(':
/* code */
MyStack.push(0);
break;
case ')':
/* code */
if(MyStack.empty()||MyStack.top()!=0)return 0;
else MyStack.pop();
break;
case '[':
/* code */
MyStack.push(1);
break;
case ']':
/* code */
if(MyStack.empty()||MyStack.top()!=1)return 0;
else MyStack.pop();
break;
case '{':
/* code */
MyStack.push(2);
break;
case '}':
/* code */
if(MyStack.empty()||MyStack.top()!=2)return 0;
else MyStack.pop();
break;
default:
return 0;
break;
}
}
if(MyStack.empty())return 1;
return 0;
}
};
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
示例:
提示:
类似于括号匹配
class Solution {
public:
string removeDuplicates(string s) {
stack<int> MyStack;
for(int i=0;i<s.size();i++){
if(!MyStack.empty()){
if(MyStack.top()==s[i]){
MyStack.pop();
}else{
MyStack.push(s[i]);
}
}else{
MyStack.push(s[i]);
}
}
string res;
int index=MyStack.size();
res.resize(MyStack.size());
while(!MyStack.empty()){
res[--index]=MyStack.top();
MyStack.pop();
}
return res;
}
};
可以直接拿字符串当栈
class Solution {
public:
string removeDuplicates(string S) {
string result;
for(char s : S) {
if(result.empty() || result.back() != s) {
result.push_back(s);
}
else {
result.pop_back();
}
}
return result;
}
};