代码随想录算法训练营第十一天|LeetCode20.有效的括号、LeetCode1047.删除字符串中的所有相邻重复项、LeetCode150.逆波兰表达式求值
2023年2月27日
第十三天补
20. 有效的括号
题目链接:20. 有效的括号
思路:
- 用栈来匹配前一个未匹配过的符号
时间复杂度:O(n)
,空间复杂度O(n)
代码:
class Solution
{
public:
bool isValid(string s)
{
std::stack<char> symbol_stack;
for (auto kuohao : s)
{
if (kuohao == '(' || kuohao == '{' || kuohao == '[')
{
symbol_stack.push(kuohao);
}
else
{
if ((kuohao == '}' && symbol_stack.size() > 0 && symbol_stack.top() == '{') ||
(kuohao == ']' && symbol_stack.size() > 0 && symbol_stack.top() == '[') ||
(kuohao == ')' && symbol_stack.size() > 0 && symbol_stack.top() == '('))
symbol_stack.pop();
else
return false;
}
}
if (symbol_stack.size() > 0)
return false;
else
return true;
}
};
总结:
- 难度不大,就是代码写得丑了点哈
- 做题体验:
哈哈
(哈哈
>嘿嘿
>哎哎
>嘤嘤
) - 时间:
10min
二刷
1047. 删除字符串中的所有相邻重复项
题目链接:1047. 删除字符串中的所有相邻重复项
思路:
- 和匹配括号接近,这题也是用栈保存上一个未被匹配过的字母
- 将栈中元素依次抛出存入字符串中时,得到的字符串和我们期望的结果是相反的,所以需要将字符串再逆序
- 更好的方法是直接用字符串实现栈
用字符串实现栈(代码简洁,空间和时间都更优)
时间复杂度:O(n)
,空间复杂度O(n)
代码:
class Solution
{
public:
string removeDuplicates(string s)
{
string res = "";
for(auto a:s)
{
if(s.empty() || a!= res.back())
res.push_back(a);
else
res.pop_back();
}
return res;
}
};
直接用栈实现
时间复杂度:O(n)
,空间复杂度O(n)
代码:
class Solution
{
public:
string removeDuplicates(string s)
{
stack<char> letter;
for (auto a : s)
{
if (letter.size() == 0 || (letter.size() > 0 && a != letter.top()))
{
letter.push(a);
}
else
{
letter.pop();
}
}
s.clear();
while (letter.size() > 0)
{
s.push_back(letter.top());
letter.pop();
}
std::reverse(s.begin(), s.end());
return s;
}
};
总结:
- 灵活使用合适的容器,充分掌握stl,这仍是我学习C++过程中需要不断提高的地方
- 做题体验:
哈哈
(哈哈
>嘿嘿
>哎哎
>嘤嘤
) - 时间:
10min
一刷
150. 逆波兰表达式求值
题目链接:150. 逆波兰表达式求值
思路:
- 和上面两题接近,我们可以使用栈来存储待运算的上两个数字
- 这边要注意的是,每次要找寻前两个数字,以及要将运算好的结果插入回栈中
时间复杂度:O(n)
,空间复杂度O(1)
代码:
class Solution
{
public:
int evalRPN(vector<string> &tokens)
{
stack<int> num;
for (auto a : tokens)
{
// 在作用域外先声明变量,避免重复申请内存空间的时候的开销
int temp_1;
int temp_2;
// 遇到运算符进行运算
if (a == "+")
{
temp_1 = num.top();
num.pop();
temp_2 = num.top();
num.pop();
num.push(temp_1 + temp_2);
}
else if (a == "-")
{
temp_1 = num.top();
num.pop();
temp_2 = num.top();
num.pop();
num.push(temp_2 - temp_1);
}
else if (a == "*")
{
temp_1 = num.top();
num.pop();
temp_2 = num.top();
num.pop();
num.push(temp_2 * temp_1);
}
else if (a == "/")
{
temp_1 = num.top();
num.pop();
temp_2 = num.top();
num.pop();
num.push(temp_2 / temp_1);
}
else
{
num.push(atoi(a.c_str()));
}
}
// 只要给到的数组规范,算到最后肯定只剩一个数,那就是结果
return num.top();
}
};
总结:
- 难度不大,但不妨碍这是个好题,让学习数据结构过程中的学习者更好的理解计算机运算的逻辑,以及初尝前中后序遍历的思想
- 这题代码还是写的丑了点
- 做题体验:
哈哈
(哈哈
>嘿嘿
>哎哎
>嘤嘤
) - 时间:
15min
一刷