Original post address: http://blog.leanote.com/post/dawnmagnet/lc1190
subject
Give a string {s (containing only lowercase letters and parentheses).
Please reverse each pair of matching strings in parentheses layer by layer in the order from inside to outside parentheses, and return the final result.
Note that your results should not contain any parentheses.
Example 1:
Input: s = "(abcd)" Output: "dcba"
Example 2:
Input: s = "(u(love)i)" Output: "iloveu"
Example 3:
Input: s = "(ed(et(oc))el)" Output: "leetcode"
Example 4:
Input: s = "a(bcdefghijkl(mno)p)q" Output: "apmnolkjihgfedcbq"
Tips:
- 0 <= s.length <= 2000
- s contains only lowercase letters and parentheses
- We make sure that all parentheses appear in pairs
Example: s = "a(b(c(d)e)f)g" answer: "afcdebg"
Generally speaking, three layers are enough to find rules. So we put three parentheses
Let's scatter this example a little
[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-7ogq94qr-1621999217623)( https://leanote.com/api/file/getImage?fileId=60adb1ccab644116e5006658 )]
Then use a line to connect the order of the answers here
[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-nscafofd-1621999217625)( https://leanote.com/api/file/getImage?fileId=60adb34dab644116e500666a )]
Does it feel a little regular?
What if we add parentheses to our system and jump only when we encounter parentheses?
[the transfer of external chain pictures fails. The source station may have anti-theft chain mechanism. It is recommended to save the pictures and upload them directly (img-trtmr9hh-1621999217627)( https://leanote.com/api/file/getImage?fileId=60adbab6ab644118e9006709 )]
It's clear at once (hand drawing is too tired)
Every time you encounter a bracket, you will jump to another bracket that matches it, and the direction will change
In this case, we will maintain a cur pointer to represent the current position and a direc to represent the direction of the next step.
Logic is that every time cur points to a bracket, it jumps to another bracket that matches it, and the direction is opposite (i.e. reverse)
As for how to get another matching bracket of the bracket, we still have to use the stack to realize the matching of the bracket and save it to an unordered_map, which is convenient to obtain at the time of O(1).
C + + code
class Solution { public: string reverseParentheses(string s) { stack<int> stk; unordered_map<int, int> m; int n = s.size(); for (int i = 0; i < n; ++i) { if (s[i] == '(') { stk.push(i); } else if (s[i] == ')') { int pre = stk.top(); stk.pop(); m[i] = pre; m[pre] = i; } } int cur = 0, direc = 1; string res; while (cur < n) { if (isalpha(s[cur])) { res.push_back(s[cur]); cur += direc; } else { direc = -direc; cur = m[cur] + direc; } } return res; } };
Rust code
use std::collections::*; impl Solution { pub fn reverse_parentheses(s: String) -> String { let mut stack = vec![]; let mut m = HashMap::new(); let n = s.len(); for (i, ch) in s.chars().enumerate() { match ch { '(' => stack.push(i), ')' => { let pre = stack.pop().unwrap(); m.insert(i as i32, pre as i32); m.insert(pre as i32, i as i32); }, _ => (), } } let mut cur = 0i32; let mut direc = 1i32; let s_byte = s.into_bytes(); let mut res = vec![]; while (cur < n as i32) { if (s_byte[cur as usize] > 50) { res.push(s_byte[cur as usize]); cur += direc; } else { direc = -direc; cur = m.get(&cur).unwrap() + direc; } } String::from_utf8(res).unwrap() } }