Longest Valid Parentheses 解题报告

原题:Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.

For "(()", the longest valid parentheses substring is "()", which has length = 2.

Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4.

LeetCode:https://leetcode.com/problems/longest-valid-parentheses/

思路:使用动态规划,令s[i]表示字符串的第i个字符,dp[i]表示以s[i]为结束符的最长合法字符串的长度,此题转化成最最大的dp[i]。
dp[]初始化全部都是0。
遍历s,如果s[i]是“(”,那么放入栈中(left自增1),left表示目前可用的“(”数目。
如果s[i]是“)”,并且left大于0,那么可以根据dp之前的值来计算当前的dp。

如果dp[i – 1] == 0,那么s[i – 1]一定是一个“(”。
如果dp[i – 1] != 0,那么s[i – 1] 一定是一个“)”,并且s[i - 1 – dp[i - 1]]一定是一个“(”(即当前栈顶的左括号)。

所以无论是dp[i – 1] == 0 还是dp[i – 1] != 0,都有:
dp[i] = dp[i - 1] + 2;

但是我们还漏掉了一种场景,例如以(())为例,它的最左边可能还有(),如()(()),需要把最左边的合法串也加进来。于是有:dp[i] += (i - dp[i]) > 0 ? dp[i - dp[i]] : 0;

public class Solution {
    public intlongestValidParentheses(String s) {
        int ret = 0;
        // dp[i]表示以i为结束符的最长合法字符串
        int[] dp = new int[s.length()];
        int left = 0; // 可用的 '(' 数目
        for (int i = 0; i < s.length(); ++i) {
            // 注意这个地方不要把String转化成char数组,否则String太大时会超时!
            if (s.charAt(i) == '(') {
                ++left;
            } else {
                if (left > 0) {
                    dp[i] = dp[i - 1] + 2;
                    dp[i] += (i - dp[i]) > 0 ? dp[i - dp[i]] : 0;
                    ret = Math.max(ret, dp[i]);
                    --left;
                }
            }
        }
 
        return ret;
    }
 
   
    public static void main(String[] args) {
        Solution s = new Solution();
        String str = "()()";
        System.out.println(s.longestValidParentheses(str));
    }
}

你可能感兴趣的:(Longest Valid Parentheses 解题报告)