You are given a string s
that consists of lower case English letters and brackets.
Reverse the strings in each pair of matching parentheses, starting from the innermost one.
Your result should not contain any brackets.
Example 1:
Input: s = "(abcd)"
Output: "dcba"
Example 2:
Input: s = "(u(love)i)"
Output: "iloveu"
Explanation: The substring "love" is reversed first, then the whole string is reversed.
Example 3:
Input: s = "(ed(et(oc))el)"
Output: "leetcode"
Explanation: First, we reverse the substring "oc", then "etco", and finally, the whole string.
Example 4:
Input: s = "a(bcdefghijkl(mno)p)q"
Output: "apmnolkjihgfedcbq"
Constraints:
0 <= s.length <= 2000
s
only contains lower case English characters and parentheses.- It's guaranteed that all parentheses are balanced.
這道題給了一個只含有小寫字母和括號的字符串s,現在讓從最內層括號開始,每次都反轉括號內的所有字符,然后可以去掉該內層括號,依次向外層類推,直到去掉所有的括號為止。可能有的童鞋拿到題后第一反應可能是遞歸到最內層,翻轉,然后再一層一層的出來。這樣的做的話就有點麻煩了,而且保不齊還有可能超時。比較好的做法就是直接遍歷這個字符串,當遇到字母時,將其加入結果 res,當遇到左括號時,將當前 res 的長度加入一個數組 pos,當遇到右括號時,取出 pos 數組中的最后一個數字,並翻轉 res 中該位置到結尾的所有字母,因為這個區間剛好就是當前最內層的字母,這樣就能按順序依次翻轉所有括號中的內容,最終返回結果 res 即可,參見代碼如下:
解法一:
class Solution {
public:
string reverseParentheses(string s) {
string res;
vector<int> pos;
for (char c : s) {
if (c == '(') {
pos.push_back(res.size());
} else if (c == ')') {
int idx = pos.back();
pos.pop_back();
reverse(res.begin() + idx, res.end());
} else {
res.push_back(c);
}
}
return res;
}
};
這道題居然還有 O(n) 的解法,由 lee215 大神提出的一種類似蟲洞的解法,驚為天人,評論區有人調侃到 LeetCode 應該改名為 Lee'sCode,哈哈,確實很形象。這種解法首先要建立每一對括號位置之間的映射,而且是雙向映射,即左括號位置映射到右括號位置,同時右括號位置也要映射到左括號位置,這樣在第一次遇到左括號時,就可以直接跳到對應的右括號,然后往前遍歷,當下次遇到右括號時,就直接跳到其對應的左括號,然后往后遍歷,這樣實際相當於在嵌套了兩層的括號中,是不用翻轉的,因為只有奇數嵌套才需要翻轉,用這種邏輯遍歷,就可以串出最終正確的結果,由於遍歷順序不停在改變,所以用一個變量d來控制方向,初始化為1,當需要變換了就取相反數即可,參見代碼如下:
解法二:
class Solution {
public:
string reverseParentheses(string s) {
string res;
int n = s.size();
vector<int> pos, pair(n);
for (int i = 0; i < n; ++i) {
if (s[i] == '(') {
pos.push_back(i);
} else if (s[i] == ')') {
int idx = pos.back();
pos.pop_back();
pair[i] = idx;
pair[idx] = i;
}
}
for (int i = 0, d = 1; i < n; i += d) {
if (s[i] == '(' || s[i] == ')') {
i = pair[i];
d = -d;
} else {
res += s[i];
}
}
return res;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/1190
參考資料:
https://leetcode.com/problems/reverse-substrings-between-each-pair-of-parentheses/