碎碎念:坚持住。
参考:代码随想录
232.用栈实现队列
题目链接
思想
用两个栈来实现队列,队列要做到先进先出,但是栈的特性是先进后出,所以要用到一个栈作为入栈,一个栈作为出栈。
一旦有弹出的行为,要把入栈里所有的元素都放到出栈里 ,不全部放入的话会出现混乱。
题解
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();
stOut.push(res);
return res;
}
bool empty() {
return stIn.empty() && stOut.empty();
}
};
class MyQueue:
def __init__(self):
self.stack_in = []
self.stack_out = []
def push(self, x: int) -> None:
self.stack_in.append(x)
def pop(self) -> int:
if self.stack_out:
return self.stack_out.pop()
else:
for i in range(len(self.stack_in)):
self.stack_out.append(self.stack_in.pop())
return self.stack_out.pop()
def peek(self) -> int:
res = self.pop()
self.stack_out.append(res)
return res
def empty(self) -> bool:
return not(self.stack_in or self.stack_out)
反思
注意top是获取栈顶的元素,pop才是把元素弹出了。
not(空列表)会返回Ture
225. 用队列实现栈
题目链接
思想
用一个队列就可以模拟栈。
队列模拟栈弹出元素的时候,把前size-1个元素依次弹出再加入队列即可,注意这里保留了最后一个元素,此时再弹出元素就是按照栈的顺序了。
题解
class MyStack {
public:
queue<int> que;
MyStack() {
}
void push(int x) {
que.push(x);
}
int pop() {
int size = que.size();
size--; // 把前size-1个元素都弹出
while (size--) {
que.push(que.front()); // front出口处的第一个元素
que.pop();
}
int res = que.front();
que.pop();
return res;
}
int top() {
return que.back();
}
bool empty() {
return que.empty();
}
};
class MyStack:
def __init__(self):
self.que = deque()
def push(self, x: int) -> None:
self.que.append(x)
def pop(self) -> int:
for i in range(len(self.que) - 1):
self.que.append(self.que.popleft())
return self.que.popleft()
def top(self) -> int:
return self.que[-1]
def empty(self) -> bool:
return not self.que
反思
还要熟悉STL
20. 有效的括号
题目链接
思想
剪枝操作:如果串的长度为奇数的时候是一定可以发现不匹配的括号的。
遇见左括号的时候将对应的右括号加入栈,为的是后面匹配的时候方便。
题解
class Solution {
public:
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] == '(') st.push(')');
else if (s[i] == '{') st.push('}');
else if (s[i] == '[') st.push(']');
// 3. 字符串还没有遍历完,但是栈空了,说明有多余的右括号
// 2. 遍历时括号没有匹配上
else if (st.empty() || st.top() != s[i]) return false;
else st.pop();
}
// 1. 遍历完了字符串但是栈不为空,说明有多余的左括号
return st.empty();
}
};
class Solution:
def isValid(self, s: str) -> bool:
if len(s) % 2 != 0: return False
stack = []
for item in s:
if item == '(':
stack.append(')')
elif item == '{':
stack.append('}')
elif item == '[':
stack.append(']')
elif not stack or stack[-1] != item:
return False
else:
stack.pop()
return True if not stack else False
反思
本题把每种情况分清楚就比较好写了。
1047. 删除字符串中的所有相邻重复项
题目链接
思想
和括号匹配那道题差不多的思路。注意最后输出的时候要翻转一下。
题解
class Solution {
public:
string removeDuplicates(string s) {
stack<char> st;
for (char item : s) {
if (st.empty() || item != st.top()) {
st.push(item);
} else {
st.pop();
}
}
string result = "";
while (!st.empty()) {
result += st.top();
st.pop();
}
reverse(result.begin(), result.end());
return result;
}
};
class Solution:
def removeDuplicates(self, s: str) -> str:
res = []
for item in s:
if not res or res[-1] != item:
res.append(item)
else:
res.pop()
return "".join(res)