LeetCode 20 Valid Parentheses Parentheses match

The classic bracket matching judgment problem, because it is a relatively long memory, I can't remember how to do it, so I thought about it for a while and then figured it out.

It is relatively simple to have only one type of parenthesis. Just record the number of positive and negative parentheses and scan from left to right to ensure that there are no unmatched right parentheses in the middle. But this method has no contribution to the solution of this problem, because if we use the same method, we will find that the two substrings "(({(()" and "(((({)" are matched to the end The state recorded is the same when the latter is clearly a string that does not meet the requirements.

Returning to this question, a simple idea is to confirm whether each parenthesis matches, that is, for each parenthesis, find another back parenthesis that matches it. According to the string that satisfies bracket matching, if A is matched, then "(A)" is also matched, that is to say, if we process from left to right, each time for a left bracket '(' , try skipping the middle A to see if there is a closing parenthesis ')' to match.

The simplest way is to process each opening bracket separately, ignore brackets of different types from itself during the process of sweeping to the right, and then use only one bracket until the closing bracket that matches the current opening bracket is found, and then Remove this pair of parentheses from the original string, loop until the entire string is cleared, and return true.

The time is O(n²), and it will be WA, because ignoring different types of parentheses, the example of "({)}" will not pass.

Then use the recursive method to solve, every time the current left parenthesis l finds the right parenthesis r, verify whether [l+1, r-1] is legal, solve the above WA problem, and the time complexity is still O(n²).

It is natural to think of an improved idea. Since recursion is used, we can perform the matching of the left and right parentheses and the validity verification of the middle substring at the same time. The method is as follows:

Construct the following next function int next(pos) to find the right parenthesis corresponding to the left parenthesis at the pos position:

  • For the current position pos, confirm whether it is a left parenthesis, if not, the original string is invalid
  • Boundary processing, check if pos+1 matches the current position, if so, return pos+2
  • Call next(pos+1) recursively, that is, for the part of "(A)" that removes A, but because there may be "(()())" - that is, A="()()" - and other In a similar situation, we judge whether next(pos+1) matches the current left parenthesis, if not, i=next(pos+1), and loop i=next(i) until we get the The left parenthesis of pos corresponds to the right parenthesis of i
  • If the above i is out of bounds, that is, exceeds the length of the original string len, the original string is invalid

In this way, each position of the string is accessed only once, that is, the time complexity is reduced to O(n), and not only the legality check is completed, but also the matching of each pair of parentheses is completed.

code show as below:

class Solution {
public:
    bool isleft(char c){
        return c == '(' || c == '[' || c == '{';
    }
    bool isright(char c){
        return c == ')' || c == ']' || c == '}';
    }
    bool ispair(char lc, char rc){
        if (lc == '(' && rc == ')')
            return true;
        if (lc == '[' && rc == ']')
            return true;
        if (lc == '{' && rc == '}')
            return true;
        return false;
    }
    int next(int pos, int len, const string &s){
        if (!isleft(s[pos]) || pos+1 >= len)
            return -1;
        if (ispair(s[pos], s[pos+1]))
            return pos + 2;
        int i = next(pos+1, len, s);
        while(i < len){
            if (i == -1)
                return -1;
            if (ispair(s[pos], s[i]))
                return i + 1;
            i = next(i, len, s);
        }
        return -1;
    }
    bool isValid(string s) {
        int len = s.length();
        int i = 0;
        while(i < len){
            i = next(i, len, s);
            if (i == -1)
                return false;
        }
        return true;
    }
};

The end result is also pretty good:

Although the difficulty of this question is easy, aside from the simplest O(n²) approach, I personally think that adding a medium on the leetcode side is no problem.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326383856&siteId=291194637