LeetCode 20 有效的括号
题目链接:20. 有效的括号
做题情况:这道题目以前做过好几遍,所以梳理成章地很快就ac出来了,里面那个第一个小技巧自己也记得:①在匹配左括号的时候,右括号先入栈,就只需要比较当前元素和栈顶相不相等就可以了,比左括号先入栈代码实现要简单的多了!②首先判断字符串数量大小是否为2的倍数来直接做一个提前判断(这个当时也想到了,不过没有在代码中实现出来),不过看完卡哥视频和代码随想录书相关部分后,进行代码对比,发现自己写的代码总是那么不专业和冗余,我的具体ac代码如下:
class Solution {
public:
bool isValid(string s) {
int n=s.size();
//此处可以先判断是否为2的倍数来做一个提前做剪枝操作
stack<char>st;
for(int i=0;i<n;i++){
//以下代码的书写可以更简洁些,好好和卡哥所给的代码进行比较然后学习
if(s[i]=='('){
st.push(')');
}else if(s[i]=='{'){
st.push('}');
}else if(s[i]=='['){
st.push(']');
}
else{
if(st.empty()){
return false;
}else{
char tmp=st.top();
st.pop();
if(tmp!=s[i]){
return false;
}
}
}
}
if(st.empty()){
return true;
}else{
return false;
}
}
};
而卡哥所给的代码如下:
class Solution {
public:
bool isValid(string s) {
if (s.size() % 2 != 0) return false; // 如果s的长度为奇数,一定不符合要求
stack<char> st;
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(']');
// 第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号 return false
// 第二种情况:遍历字符串匹配的过程中,发现栈里没有我们要匹配的字符。所以return false
else if (st.empty() || st.top() != s[i]) return false;
else st.pop(); // st.top() 与 s[i]相等,栈弹出元素
}
// 第一种情况:此时我们已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false,否则就return true
return st.empty();
}
};
代码书写的简洁不冗余以及编程时候的小技巧很重要,需要多加学习和练习
LeetCode 1047 删除字符串中的所有相邻重复项
题目链接:1047. 删除字符串中的所有相邻重复项
做题情况:由于本题放在栈和队列这个章节,所以自然而然想到用栈来做题目,如果真的是裸题目给出,真的还完全想不到,不过这个地方有个很要注意的地方:就是字符串操作,str +=a和str= str+a的区别,后者书写会带来比较大时间和空间消耗,像本题后者书写就会超时,具体见代码里面注释,如下:
class Solution {
public:
string removeDuplicates(string s) {
int n=s.size();
stack<char>st;
for(int i=0;i<n;i++){
if(st.empty()){
st.push(s[i]);
}else{
char tmp=st.top();
if(tmp==s[i]){
st.pop();
}else{
st.push(s[i]);
}
}
}
string result="";
while(!st.empty()){
// char tmp=st.top();
// result =result+tmp;
//或者
//result =result+st.top();
//上述这两种写法提交都会超时,注意str +=a和str= str+a的区别
result +=st.top();
st.pop();
}
reverse(result.begin(),result.end());
return result;
}
};
看完卡哥视频和代码随想录书相关部分后,发现这次代码的书写还是和上题目一样,冗余不专业,卡哥的代码如下:
class Solution {
public:
string removeDuplicates(string S) {
stack<char> st;
for (char s : S) {
if (st.empty() || s != st.top()) {
st.push(s);
} else {
st.pop(); // s 与 st.top()相等的情况
}
}
string result = "";
while (!st.empty()) { // 将栈中元素放到result字符串汇总
result += st.top();
st.pop();
}
reverse (result.begin(), result.end()); // 此时字符串需要反转一下
return result;
}
};
这道题目还可以直接拿字符串作为栈,这样就省去了栈还要转为字符串的操作。还可以用双指针法,所以双指针法要时刻记在自己心中,具体见卡哥的讲解
LeetCode 150 逆波兰表达式求值
题目链接:150. 逆波兰表达式求值
做题情况:这道题目以前也做过,所以也ac出来了,但是看完卡哥视频和代码随想录书相关部分后,发现自己代码和前两题目一样,冗余不专业以及少一些技巧性的东西, 比上题目更严重,自己具体代码如下:
class Solution {
public:
//在操作栈时候注意数据类型所能容纳的大小,不然会溢出
int evalRPN(vector<string>& tokens) {
int n=tokens.size();
//栈的存储可以变成数字的,不需要是字符串的
stack<string>st;
st.push(tokens[0]);
for(int i=1;i<n;i++){
//这四个条件可以合并一下的
if(tokens[i]=="+"){
long tmp1=stol(st.top());
st.pop();
long tmp2=stol(st.top());
st.pop();
long tmp=tmp1+tmp2;
st.push(to_string(tmp));
}else if(tokens[i]=="-"){
long tmp1=stol(st.top());
st.pop();
long tmp2=stol(st.top());
st.pop();
long tmp=tmp2-tmp1;
st.push(to_string(tmp));
}else if(tokens[i]=="*"){
long tmp1=stol(st.top());
st.pop();
long tmp2=stol(st.top());
st.pop();
long tmp=tmp1*tmp2;
st.push(to_string(tmp));
}else if(tokens[i]=="/"){
long tmp1=stol(st.top());
st.pop();
long tmp2=stol(st.top());
st.pop();
long tmp=tmp2/tmp1;
st.push(to_string(tmp));
}else{
st.push(tokens[i]);
}
}
return stoi(st.top());
}
};
而卡哥的代码如下:
class Solution {
public:
int evalRPN(vector<string>& tokens) {
// 力扣修改了后台测试数据,需要用longlong
stack<long long> st;
for (int i = 0; i < tokens.size(); i++) {
if (tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/") {
long long num1 = st.top();
st.pop();
long long num2 = st.top();
st.pop();
if (tokens[i] == "+") st.push(num2 + num1);
if (tokens[i] == "-") st.push(num2 - num1);
if (tokens[i] == "*") st.push(num2 * num1);
if (tokens[i] == "/") st.push(num2 / num1);
} else {
st.push(stoll(tokens[i]));
}
}
int result = st.top();
st.pop(); // 把栈里最后一个元素弹出(其实不弹出也没事)
return result;
}
};
好好学习一些编程小技巧和代码书写简洁性,这个很重要
今天三道题目都ac出来了,主要知道由于在栈的章节知道用栈,如果第一次见还真做不出,不过注意一些编程小技巧和代码书写简洁可读不冗余性,时刻要铭记栈在消除元素中的应用,因为栈可以存放遍历过的元素,当遍历当前的这个元素的时候,去栈里看一下我们是不是遍历过相同数值的相邻元素啥的从而达到消除操作。关键注意栈可以存放先前已经遍历过的元素这个很重要,今天所有做下来总共花了三四个小时,一切正常。
贵在坚持,加油,共勉