六月集训(第14天)—栈
栈
1. 剑指 Offer 31. 栈的压入、弹出序列
思路:
模拟栈的压入过程 ,并利用一个指针指向popped序列的起始位置。当栈顶和popped序列相同时,弹栈,popped的指针向后移动一位;否则将pushed序列中的元素依次压栈。如果最后栈弹空,且指针指向了popped末尾,则满足题意。
class Solution {
public:
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
int pushed_size = pushed.size(), i = 0, j = 0;
stack<int> S;
while (i < pushed_size && j < pushed_size) {
while (i < pushed_size && (S.empty() || S.top() != popped[j])) {
S.push(pushed[i++]);
}
while (j < pushed_size && !S.empty() && S.top() == popped[j]) {
S.pop();
j++;
}
}
if (S.empty() && j == pushed_size) return true;
return false;
}
};
2. 946. 验证栈序列
思路:
和第一题一样。
class Solution {
public:
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
int pushed_size = pushed.size(), i = 0, j = 0;
stack<int> S;
while (i < pushed_size && j < pushed_size) {
while (i < pushed_size && (S.empty() || S.top() != popped[j])) {
S.push(pushed[i++]);
}
while (j < pushed_size && (!S.empty() && S.top() == popped[j])) {
S.pop();
j++;
}
}
if (S.empty() && j == pushed_size) return true;
else return false;
}
};
3. 856. 括号的分数
思路:
好家伙,递归博大精深,刚开始的思路是将枚举左右括号的四种组合与A+B和2*A的关系,没做出来。
再考虑成对匹配
(1) 最外侧括号成对,则返回 2 * get_score(去掉外侧括号,剩下的字串)
(2) 字符串中出现了前缀构成完整的括号的匹配,从完成匹配的位置 idx 作为分割,返回get_score(idx 之前的字串) + get_score(idx 之后的子串)
递归出口:当前字串只包含()
class Solution {
int get_scores(string s, int l, int r) {
int cnt = 0, idx = l;
if (l + 1== r) return 1;
while (idx <= r) {
cnt += (s[idx] == '(' ? 1 : (-1));
idx++;
if (cnt == 0) break;
}
if (idx == r + 1) return 2 * get_scores(s, l + 1, r - 1); // 最外侧是一对括号
else return get_scores(s, l, idx - 1) + get_scores(s, idx, r); // 在字符串中间已经出现了完整匹配的括号,则加法计分
}
public:
int scoreOfParentheses(string s) {
int s_len = s.length();
return get_scores(s, 0, s_len - 1);
}
};
4. 1190. 反转每对括号间的子串
思路:
由于括号成对出现,遍历字符串,每次将'('的位置 left 压栈,遇到')'的位置为right,此时将字符串中left ~ right部分进行翻转,并弹栈,直到遍历完整个字符串。
上述操作再原字符串中进行,所以的到的字符串还带有括号,处理一下,即可获得不带括号的答案。
class Solution {
public:
string reverseParentheses(string s) {
int s_len = s.length(), i;
stack<int> stk;
for (i = 0; i < s_len; ++i) {
if (s[i] == '(') stk.push(i); /* 记录左括号位置 */
else if (s[i] == ')') { /* 翻转区间left ~ right 的字符串 */
int l = stk.top(), r = i;
while (l < r) {
swap(s[l++], s[r--]);
}
stk.pop();
}
}
string ans;
// 获取不带括号的答案字符串
for (i = 0; i < s_len; ++i) if (s[i] != '(' && s[i] != ')') ans += s[i];
return ans;
}
};
东方欲晓,莫道君行早。

浙公网安备 33010602011771号