力扣每日一题——反转每对括号之间的子串
Posted 残星~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了力扣每日一题——反转每对括号之间的子串相关的知识,希望对你有一定的参考价值。
给出一个字符串 s(仅含有小写英文字母和括号)。
请你按照从括号内到外的顺序,逐层反转每对匹配括号中的字符串,并返回最终的结果。
注意,您的结果中 不应 包含任何括号。
示例 1:
输入:s = “(abcd)”
输出:“dcba”
示例 2:
输入:s = “(u(love)i)”
输出:“iloveu”
示例 3:
输入:s = “(ed(et(oc))el)”
输出:“leetcode”
示例 4:
输入:s = “a(bcdefghijkl(mno)p)q”
输出:“apmnolkjihgfedcbq”
思路:以s = "(u(love)i)"为例,它的最后反转结果就是i love you,我们会发现,每经过两层括号,这一层里面的文字不用反转。但是如果根据层数的但偶来判断是否反转要记录的东西太多。果断放弃这种想法
如果考虑遍历,那么我们可以从左往右进行遍历,遇到左括号记录一个空串,遇到英文字母就计入该串,遇到右括号就把该串进行翻转。但是对于括号套括号的情况,即当已经遇到左括号之后又遇到左括号,那么必须建立一个新串,在遇到该新串的右括号的时候将新串翻转加到旧串上,当遇到该旧串的右括号时,就进行再次翻转。代码如下
class Solution {
public:
string reverseParentheses(string s) {
stack<string> stk;
string str;
for (auto &ch : s) {
if (ch == '(') {
stk.push(str);
str = "";
} else if (ch == ')') {
reverse(str.begin(), str.end());
str = stk.top() + str;
stk.pop();
} else {
str.push_back(ch);
}
}
return str;
}
};
但是这时候会发现自己写的代码形成层状结构,时间复杂度会随着括号的增多而逐渐次方化,这不是我们想看到的
那如果想摆脱层状结构,那么最好的方法就是返回刚才的发现,每两层就会有一层不用反转,记录左右括号的对应坐标备用,先从左往右遍历,遇到左括号就根据先前记下的对应关系到右括号逆序遍历,遇到下一层的右括号时,就去该层的左括号顺序遍历,那这样就实现了每两层就有一层不用改变顺序,即按原来顺序执行。不用重复建立新的字符串来存放最新的字符串,时间复杂度一下就变成了O(n)。代码借鉴于力扣官方答解
class Solution {
public:
string reverseParentheses(string s) {
int n = s.length();
vector<int> pair(n);
stack<int> stk;
for (int i = 0; i < n; i++) {
if (s[i] == '(') {
stk.push(i);
} else if (s[i] == ')') {
int j = stk.top();
stk.pop();
pair[i] = j, pair[j] = i;
}
}
string ret;
int index = 0, step = 1;
while (index < n) {
if (s[index] == '(' || s[index] == ')') {
index = pair[index];
step = -step;
} else {
ret.push_back(s[index]);
}
index += step;
}
return ret;
}
};
以上是关于力扣每日一题——反转每对括号之间的子串的主要内容,如果未能解决你的问题,请参考以下文章