LeetCode 가장 긴 유효한 괄호 (32 질문)

LeetCode 가장 긴 유효한 괄호

@author : Jingdai
@date : 2020.10.10

주제 설명 (32 개 질문)

'('')'문자열 포함하는 경우 가장 긴 하위 문자열을 찾으려면 유효한 괄호가 포함됩니다.

  • 샘플 입력

    ")()())"
    
  • 샘플 출력

    4
    
  • 설명

    最长有效括号子串为 "()()"
    

아이디어

  • 방법 1 dp

    동적 프로그래밍 : 문자열 배열의 길이와 동일한 길이를 설정하기 dp[]위해 배열 dp[i]i끝 괄호 유효 길이의 가장 긴 부분 문자열을 나타냅니다 .

    • 초기 조건

      분명히, 초기 조건 dp[0] = 0.

    • 해결 과정

      1. s.charAt(i) == '('dp[i] = 0 .

      2. s.charAt(i) == ')'s.charAt(i-1) == '('dp[i] = dp[i-2] + 2 .

        아래 그림과 같이.

        여기에 사진 설명 삽입

      3. s.charAt(i) == ')'s.charAt(i-1) == ')'할 때, 만약 s.charAt(i-1-dp[i-1]) == '(', 만약 dp[i] = dp[i-1] + 2 + dp[i-1-dp[i-1] - 1]. 아래 그림과 같이.

      여기에 사진 설명 삽입

    • 지침

      경계 조건의 판단, 즉 아래 첨자가 경계를 넘어서는 안됩니다.

    아래 코드를 참조하십시오.

  • 방법 2 스택

    당신이 그것의 앞에 유효한 브래킷의 문자열의 어느 곳에서나 발견 할 것이다 첫번째 것은의 (자신을 포함) '('수는 동일 항상보다 큰 ')'수, 때 ')'몇 번 더, 그것은 확실히 유효한 문자열 브래킷이 아닌 . 스택을 조작하려면이 속성을 사용하십시오 stack.

    충족되면 순회 문자열 '('이 해당 인덱스를 푸시합니다. 그렇다면 쌍을 ')'나타낼 수 있으며 '('스택이 비어 있지 않은 경우 팝업되어 유효한 문자열을 구성하는 오른쪽 대괄호를 표시합니다. 아래 첨자의 끝은 현재 아래 첨자에서 스택의 최상위 요소를 뺀 값입니다. 스택이 비어 있으면 ')'다음 용도로 스택의 현재 인덱스 인 유효한 대괄호 문자열이 더 많이 표시 됩니다.

    토론의 분할이 아닌 전체 통합을 통과하기 위해 -1 첫 번째 푸시를 통과하기 전에 ')'스택에서 첫 번째 나타냅니다 . 아래 코드를 참조하십시오.

  • 방법 3 정방향 및 역방향 순회

    그리고 스택은 다소 비슷한 아이디어였습니다. 그것은 유효한 모든 괄호의 하위 문자열이며, 그 앞에는 '('항상 ')'숫자 보다 큰 숫자와 같으며 , ')'더 많은 시간이 확실히 유효한 문자열 대괄호가 아닙니다.

    첫째, 머리에서 문자열을 가로 지르는 녹음 leftright표현 '('')'숫자. 경우 right > left에 불가능이 있었다, 그것은 나타냅니다 효율적으로, 브래킷을 훈련 left하고 right트래버스를 계속하도록 설정 0. left == right, 대표 괄호의 유효한 문자열을 발견했다. 업데이트 길이.

    그러나 이것은 사례 '('보다 더 큰 상황을 놓칠 것 ')'입니다. 예를 들어 괄호 안에 유효한 문자열을 찾을 수 "(()"없으므로 꼬리에서 동일한 것을 사용하는 아이디어는 '('더 많은 시간이 지나면 A가 아니어야합니다. 유효한 괄호 문자열은 첫 번째 순회에서 누락 된 경우를 고려할 수 있습니다. right < left, 그것은 것 left, 그리고 right세트 0으로 통과 할 계속합니다. left == right, 대표 괄호의 유효한 문자열을 발견했다. 업데이트 길이. 아래 코드를 참조하십시오.

암호

  • 방법 1

    public int longestValidParentheses(String s) {
           
           
        int[] dp = new int[s.length()];
    
        int longestLen = 0;
        for (int i = 1; i < s.length(); i++) {
           
           
            if (s.charAt(i) == ')') {
           
           
                if (s.charAt(i-1) == '(') {
           
           
                    dp[i] = i-2 >= 0 ? (dp[i-2] + 2) : 2; // process when i = 1
                    longestLen = dp[i] > longestLen ? dp[i] : longestLen; 
                } else if (s.charAt(i-1) == ')' && i-1-dp[i-1] >= 0 && s.charAt(i-1-dp[i-1]) == '(') {
           
           
                    if (i-1-dp[i-1]-1 >= 0) {
           
           
                        dp[i] = dp[i-1] + 2 + dp[i-1-dp[i-1]-1];
                    } else {
           
           
                        dp[i] = dp[i-1] + 2;
                    }
                    longestLen = dp[i] > longestLen ? dp[i] : longestLen;
                }
            }
        }
        return longestLen;
    }
    
  • 방법 2

    public int longestValidParentheses(String s) {
           
           
            
        LinkedList<Integer> stack = new LinkedList<>();
        stack.add(-1);
        int longestLen = 0;
        for (int i = 0; i < s.length(); i++) {
           
           
            if (s.charAt(i) == '(') {
           
           
                stack.addFirst(i);
            } else {
           
           
                stack.poll();
                if (stack.size() == 0) {
           
           
                    stack.addFirst(i);
                } else {
           
           
                    longestLen = longestLen > i - stack.getFirst() ? longestLen : i - stack.getFirst();
                }
            }
        }
    
        return longestLen;
    }
    
  • 방법 3

    public int longestValidParentheses(String s) {
           
           
        int left = 0;
        int right = 0;
        int longestLen = 0;
        for (int i = 0; i < s.length(); i++) {
           
           
            if (s.charAt(i) == '(') {
           
           
                left++;
            } else {
           
           
                right++;
            }
    
            if (left == right) {
           
           
                longestLen = longestLen > 2 * left ? longestLen : 2 * left; 
            } else if (right > left) {
           
           
                left = 0;
                right = 0; 
            }
        }
        left = 0;
        right = 0;
        for (int i = s.length() - 1; i >= 0; i--) {
           
           
            if (s.charAt(i) == '(') {
           
           
                left++;
            } else {
           
           
                right++;
            }
    
            if (left == right) {
           
           
                longestLen = longestLen > 2 * left ? longestLen : 2 * left; 
            } else if (left > right) {
           
           
                left = 0;
                right = 0; 
            }
        }
        return longestLen;
    }
    

추천

출처blog.csdn.net/qq_41512783/article/details/109004044