[C++&Rust]No.1190 inverts the substring between each pair of parentheses

Posted by ramas on Tue, 08 Feb 2022 08:30:38 +0100

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
#Train of thought analysis this is a string processing problem. From the meaning of the problem, it can be concluded that the text in brackets needs to be flipped. If we use side processing and side flipping, if we encounter a string in the form of ` ((((ABCDEFG))) ', it will be flipped many times, and the complexity reaches $O(N^2) $, where $N $is the length of the string. So if we want to finish processing at one time, is it possible. Of course, it is possible. After all, the answer equivalent to the final output is only an arrangement of the original string. We only need to find an appropriate traversal process or traversal order to output the answer at one time. Let's look at a slightly more complex example first, and we'll start looking for rules here.
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()
    }
}

Topics: leetcode