这道题没有什么难度,主要是熟练栈和队列的操作。其中从下面代码可以看到peek()的实现,直接用了pop()的操作,要不然判空的操作要再写一遍。一定要懂得复用,功能相近的函数要抽象出来,不要大量的复制粘贴,很容易出问题!
class MyQueue
{
public:
stack<int> stIn;
stack<int> stOut;
MyQueue()
{
}
void push(int x)
{
stIn.push(x);
}
int pop()
{
if (stOut.empty())
{
while (!stIn.empty())
{
stOut.push(stIn.top());
stIn.pop();
}
}
int result = stOut.top();
stOut.pop();
return result;
}
int peek()
{
int res = this->pop(); // 直接使用已有的pop函数
stOut.push(res); // 因为pop函数弹出了元素res,所以再添加回去
return res;
}
bool empty()
{
return stIn.empty() && stOut.empty();
}
};
一个队列在模拟栈弹出元素的时候只要将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部,此时再去弹出元素就是栈的顺序了。
class MyStack {
public:
queue<int> que;
MyStack() {
}
void push(int x) {
que.push(x);
}
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;
}
bool empty() {
return que.empty();
}
};
思路:对于一个字符串,如果字符数是奇数,直接return false;字符数量不匹配。
剩下就是遇到左括号就进栈,遇到右括号的时候,判断st是否为空,如果为空或者栈顶元素不匹配,那么直接return false;否则st出栈。一直到遍历结束。
bool isValid(string s)
{
stack<char> st;
if(s.size()%2!=0)
return false;//奇数直接返回
for (int i = 0; i < s.size(); i++)
{
if (s[i] == '(' || s[i] == '[' || s[i] == '{')
{
// 左括号入栈
st.push(s[i]);
}
else if (s[i] == ')')
{
// 遇到右括号,检查栈是否为空且栈顶元素是否匹配
if (st.empty() || st.top() != '(')
{
return false;
}
st.pop();
}
else if (s[i] == ']')
{
if (st.empty() || st.top() != '[')
{
return false;
}
st.pop();
}
else if (s[i] == '}')
{
if (st.empty() || st.top() != '{')
{
return false;
}
st.pop();
}
}
return st.empty();
}
4.1047. 删除字符串中的所有相邻重复项 - 力扣(LeetCode)
和栈相关的题都不算太绕。第一眼看的时候想用string来解决这个题,就是遍历,然后判断str[n]和str[n-1]的关系。然后发现这样的话要一直遍历下去。。。。
所以这道题打算用栈去解决,也就是说:首先用i去遍历整个字符串,一直入栈,如果top()元素与当前字符相同,那就弹出栈。遍历结束之后,将栈中元素弹出放入字符串中,最后再反转。
注意⚠️:空串:string = "";,另外注意,如果栈是空的,stack.top()没意义。。。。
string removeDuplicates(string s) {
stack<char> st;
for (int i = 0; i < s.size();i++){
if(!st.empty() && st.top() == s[i]){
st.pop();
}else{
st.push(s[i]);
}
}
string str = "";
while(!st.empty()){
str += st.top();
st.pop();
}
reverse(str.begin(), str.end());
return str;
}
思路二:直接拿字符串作为栈
string removeDuplicates(string s)
{
string res;
for (char c : s)
{
if (!res.empty() && res.back() == c)
{
res.pop_back();
}
else
{
res.push_back(c);
}
}
return res;
}
⚠️:在企业项目开发中,尽量不要使用递归!在项目比较大的时候,由于参数多,全局变量等等,使用递归很容易判断不充分return的条件,非常容易无限递归(或者递归层级过深),造成栈溢出错误(这种问题还不好排查!)