LeetCode 가장 긴 유효한 괄호
@author : Jingdai
@date : 2020.10.10
주제 설명 (32 개 질문)
'('
및')'
문자열 만 포함하는 경우 가장 긴 하위 문자열을 찾으려면 유효한 괄호가 포함됩니다.
샘플 입력
")()())"
샘플 출력
4
설명
最长有效括号子串为 "()()"
아이디어
방법 1 dp
동적 프로그래밍 : 문자열 배열의 길이와 동일한 길이를 설정하기
dp[]
위해 배열dp[i]
은i
끝 괄호 유효 길이의 가장 긴 부분 문자열을 나타냅니다 .
초기 조건
분명히, 초기 조건
dp[0] = 0
.해결 과정
때
s.charAt(i) == '('
때dp[i] = 0
.로
s.charAt(i) == ')'
와s.charAt(i-1) == '('
시dp[i] = dp[i-2] + 2
.아래 그림과 같이.
로
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 정방향 및 역방향 순회
그리고 스택은 다소 비슷한 아이디어였습니다. 그것은 유효한 모든 괄호의 하위 문자열이며, 그 앞에는
'('
항상')'
숫자 보다 큰 숫자와 같으며 ,')'
더 많은 시간이 확실히 유효한 문자열 대괄호가 아닙니다.첫째, 머리에서 문자열을 가로 지르는 녹음
left
과right
표현'('
과')'
숫자. 경우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; }