持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情
【LetMeFly】856.括号的分数
力扣题目链接:leetcode.cn/problems/sc…
给定一个平衡括号字符串 S,按下述规则计算该字符串的分数:
()得 1 分。AB得A + B分,其中 A 和 B 是平衡括号字符串。(A)得2 * A分,其中 A 是平衡括号字符串。
示例 1:
输入: "()" 输出: 1
示例 2:
输入: "(())" 输出: 2
示例 3:
输入: "()()" 输出: 2
示例 4:
输入: "(()(()))" 输出: 6
提示:
S是平衡括号字符串,且只含有(和)。2 <= S.length <= 50
方法一:特殊栈模拟
思路
假设我们有一个海纳百川的栈,各种类型的数据都能入栈。
那么我们就可以开始遍历字符串,遇到左括号就入栈,遇到右括号时:如果栈顶是左括号,那么就将左括号出栈,并且入栈“1”;如果栈顶是数值,那么在遇到左括号之前,将栈顶元素逐个出栈并累加,将左括号出栈后,将里面的元素乘二后入栈。
最终,我们将栈中的数值累加即为答案。
具体方法
分析上述思路不难发现,一共只有两类要入栈出栈的数据:“数值”和“左括号”
因此,对于C++,我们可以自定义一个结构体:
struct SpecialChar { // 左括号 / 数值
bool isLeft; // 左括号?
int val; // 若不是左括号,则此val有效
};
这样,只需要一个能存放这种结构体的栈,就实现了“数值”和“左括号”的入栈和出栈。
上述思路中,遇到右括号时,先看栈顶是否为左括号,“若为左括号则出栈并入栈1”、“若不为左括号则将所有数值出栈并求和,将左括号出栈,数值二倍后入栈”这两种情况也可以合并一下:
遇到右括号时,使用一个遍历s = 0来求和,在栈顶元素不为左括号时,不断出栈并将该数值累加到s中。若最终s值为0,则说明根本没有出栈数值,也就是说栈顶就是左括号,那么入栈“1”。否则就将s × 2后入栈。
- 时间复杂度,其中是字符串长度。
- 空间复杂度
AC代码
C++
struct SpecialChar { // 左括号 / 数值
bool isLeft; // 左括号?
int val; // 若不是左括号,则此val有效
SpecialChar(bool isLeft, int val = 0): isLeft(isLeft), val(val) {};
};
class Solution {
public:
int scoreOfParentheses(string& s) {
stack<SpecialChar> st;
for (char& c : s) {
if (c == '(') {
st.push(SpecialChar(true));
}
else { // 必有左括号
int s = 0;
while (!st.top().isLeft) {
s += st.top().val;
st.pop();
}
st.pop(); // 对应左括号出栈
st.push(SpecialChar(false, s ? s * 2 : 1));
}
}
int ans = 0;
while (st.size()) {
ans += st.top().val;
st.pop();
}
return ans;
}
};
同步发文于CSDN,原创不易,转载请附上原文链接哦~ Tisfy:letmefly.blog.csdn.net/article/det…