目录
20. 有效的括号
栈的拿手好戏!| LeetCode:20. 有效的括号_哔哩哔哩_bilibili
笔记:
1.先确定一共有三种不对应的括号排列方式
左括号多了 (({})
右括号多了 {})
左右括号不匹配 {(})
2.左括号多了:从左面开始遍历数据元素,遍历到是左面的括号,那就在栈里面放一个同样的右方向括号,当遍历到相同的右方向括号,删除掉这个元素,若左括号多了,那么在遍历完所有元素之后栈里面还会剩余括号
3.左右括号不匹配:遍历的元素和栈里面的括号不匹配
4.右括号多了:遍历元素时,栈里面没有相应的元素了
5.elseif(stack != NULL && stack.top() != s[i])一定要注意先判断栈是不是空的
一开始的错误代码:
class Solution {
public:
bool isValid(string s) {
//创建一个数据类型是int或者char的栈,如果是int,那么符号会用ASCII编码,还是可行的
stack <int> st;
int size = s.size();
//如果s的数量都不是双数,那肯定有不成对的符号,直接false
if(size%2 == 1){
return false;
}
//遍历这个字符串
for(int i = 0; i < size; i++){
if(s[i] == "("){
st.push(")");
}else if(s[i] == "{"){
st.push("}");
}else if(s[i] == "["){
st.push("]");
}else if(!s.empty() && s[i]!= st.top()){
return false;
}else{
st.pop();
}
}
//遍历所有元素之后,若stack里还有元素,那么说明左括号多了
if(!st.empty()){
return false;
}else{
return true;
}
}
};
debug记录:
s是一个字符串string,私以为可以把它看做是一个char组成的表格,所以for循环去遍历s的时候,里面的每一个元素的数据类型应该是char或者是int,与单引号' '比较
这里不是&&,而是||,不论是这两个的哪一种情况,都是错误的,栈是空的,说明右方向的括号多了,元素和栈里的数对不上说明左右括号不搭
- 还有我明明懂不能栈是空的,也就是判断语句是 st.empty() 是false,我还是写反了还写成了string s
最后正确的结果:
class Solution {
public:
bool isValid(string s) {
//创建一个数据类型是int或者char的栈,如果是int,那么符号会用ASCII编码,还是可行的
stack <int> st;
int size = s.size();
//如果s的数量都不是双数,那肯定有不成对的符号,直接false
if(size % 2 == 1) return false;
//遍历这个字符串
for(int i = 0; i < size; i++){
if(s[i] == '('){
st.push(')');
}else if(s[i] == '{'){
st.push('}');
}else if(s[i] == '['){
st.push(']');
}else if(st.empty() || s[i]!= st.top()){
return false;
}else{
st.pop();
}
}
//遍历所有元素之后,若stack里还有元素,那么说明左括号多了
if(!st.empty()){
return false;
}else{
return true;
}
}
};
1047. 删除字符串中的所有相邻重复项
栈的好戏还要继续!| LeetCode:1047. 删除字符串中的所有相邻重复项_哔哩哔哩_bilibili
看完视频的笔记:
- 利用for循环遍历字符串的元素,然后放入stack中,每放入一个就和stack.top()比较,也就是上一个放进去的元素, 如果相等,那就把栈顶的元素弹出,且继续向后遍历
- stack可以不用非得是栈,也可以是一个字符串
- 对于字符串来说,使用的是push_back(),pop_back(),back()
- 使用了栈的思想,以后删除重复项就可以这么思考
根据视频中的思路写的代码一遍过,嘿嘿:)
class Solution {
public:
string removeDuplicates(string s) {
//创建一个模拟栈的字符串s
string result;
int size = s.size();
for(int i = 0; i < size; i++){
if(result.empty() || s[i] != result.back()){
result.push_back(s[i]);
}else{
result.pop_back();
}
}
return result;
}
};
150. 逆波兰表达式求值
栈的最后表演! | LeetCode:150. 逆波兰表达式求值_哔哩哔哩_bilibili
看完视频之后的笔记:
还是借用栈的思想,用for循环遍历整体数组元素,把不是符号的数字入栈,当遍历到符号时,num1=stack.top(),stack.pop(); num1=stack.top(),stack.pop();
之后再根据相应的符号去做相应的运算,把运算结果再重新放入栈中
接着进行元素的遍历,直到遍历结束
把栈里面唯一的一个值赋值给result,return result,再释放这块内存
自己写的代码:
class Solution {
public:
int evalRPN(vector<string>& tokens) {
//创建栈用来临时存放结果和数据
stack<int> s;
int size = tokens.size();
int num1;
int num2;
int result;
int r;
for(int i = 0; i < size; i++){
if(tokens[i] == + || tokens[i] == - || tokens[i] == * || tokens[i] == /){
num1 = stack.top();
stack.pop();
num2 = stack.top();
stack.pop();
if(tokens[i] == + ){
result = num1 + num2;
}else if(tokens[i] == - ){
result = num2 - num1;
}else if(tokens[i] == * ){
result = num2 * num1;
}else{
result = num2 / num1;
}
stack.push(result);
}else{
stack.push(tokens[i]);
}
}
r = stack.top();
stack.pop();
return r;
}
};
debug记录:
debug:
1.Line 13: Char 31: error: expected expression if(tokens[i] == + || tokens[i] == - || tokens[i] == * || tokens[i] == /){
tokens这个vector里面存放的是string数据类型的数据,所以应该是 == “+”,注意是双引号
2.Line 14: Char 24: error: use of class template 'stack' requires template arguments
num1 = stack.top();
设置的栈明明是s,下面我就写成stack了
3.Line 29: Char 19: error: no matching member function for call to 'push'
s.push(tokens[i]);
s中的元素是int,但是tokens里面存放的是string,所以需要进行强制转换stoi(); 整数型
stoll(); long long型
stof(); 浮点型
成功debug的代码,嘿嘿
class Solution {
public:
int evalRPN(vector<string>& tokens) {
//创建栈用来临时存放结果和数据
stack<int> s;
int size = tokens.size();
int num1;
int num2;
int result;
int r;
for(int i = 0; i < size; i++){
if(tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/"){
num1 = s.top();
s.pop();
num2 = s.top();
s.pop();
if(tokens[i] == "+" ){
result = num1 + num2;
}else if(tokens[i] == "-" ){
result = num2 - num1;
}else if(tokens[i] == "*" ){
result = num2 * num1;
}else{
result = num2 / num1;
}
s.push(result);
}else{
s.push(stoi(tokens[i]));
}
}
r = s.top();
s.pop();
return r;
}
};
老师在网站上写的代码是 long long,应该是因为某段时间力扣更改了测试用例的大小,但是我只使用了int,也是可以正常运行的
总结
在更多的地方上应用了栈的模型,方便了运算,以后也可以在相似的地方上进行这样的思考。而且感觉学习越来越顺了,学习是有用的。一般来说看完视频就可以大致敲出来代码,然后自己慢慢debug,实在不行就去看老师的标准答案
用时:3h 中间还和同学闲聊了一会,真实时间应该小于3h