leetcode 32: 最长有效括号

import java.util.Stack;

/**
 * @Class LongestValidParentheses
 * @Description 32. 最长有效括号
 * 给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。
 * <p>
 * 示例 1:
 * 输入: "(()"
 * 输出: 2
 * 解释: 最长有效括号子串为 "()"
 * <p>
 * 示例 2:
 * 输入: ")()())"
 * 输出: 4
 * 解释: 最长有效括号子串为 "()()"
 * @Author
 * @Date 2020/7/4
 **/
public class LongestValidParentheses {
}
/**
 * 解法1:利用栈
 */
public static int longestValidParentheses(String s) {
	if (s == null || s.length() == 0) return 0;

	int maxLength = 0;
	int count = 0;
	// stack保存当前遍历到的下标位置
	Stack<Integer> stack = new Stack<Integer>();
	stack.push(-1);
	while (count < s.length()) {
		char ch = s.charAt(count);
		if (ch == '(') {
			stack.add(count);
		} else {
			stack.pop();
			if (stack.isEmpty()) {
			   stack.push(count);           // 相当于重新开始寻找有效子串
			} else {
				maxLength = Math.max(maxLength, count - stack.peek());
			}
		}
		count++;
	}

	return maxLength;
}
/**
 * 解法2: 利用动态规划
 */
public static int longestValidParentheses(String s) {
	if (s == null || s.length() == 0) return 0;
	s = " " + s;     // 添加一个空格的目的针对s="()"的特殊情况,因为下面的for循环下标从2开始的

	// dp[i] 表示以第i个字符结尾的最长有效括号的子串的长度
	int[] dp = new int[s.length()];
	int maxLength = 0;
	for (int i = 2; i < s.length(); i++) {
		// s[i]=='(' 时,dp[i] = 0
		// 只需要添加s[i]==')'的情况
		// s[i]=')' 时有两种情况是连续的
		// (a) s[i-1] =='(',即类似'()'的情况时,dp[i]=dp[i-2]+2;
		// (b) 在s[i]之前有dp[i-1]个字符是连续的,
		//      即类似'()(()())'时,dp[i]=dp[i-1]+2+dp[i-dp[i-1]-2];
		//      dp[i-1] 是其中s[3-6] 的长度;dp[i-dp[i-1]-2]是最开始的s[0,1]
		if (s.charAt(i) == ')') {
			if (s.charAt(i - 1) == '(') {
				dp[i] = dp[i - 2] + 2;
			} else if (s.charAt(i - dp[i - 1] - 1) == '(') {
				dp[i] = dp[i - 1] + 2 + dp[i - dp[i - 1] - 2];
			}
			if (dp[i] > maxLength) maxLength = dp[i];
		}
	}
	return maxLength;
}
// 测试用例
public static void main(String[] args) {
	String s = "(()";
	int ans = longestValidParentheses(s);
	System.out.println("LongestValidParentheses demo01 result:" + ans);

	s = ")()())";
	ans = longestValidParentheses(s);
	System.out.println("LongestValidParentheses demo02 result:" + ans);

	s = ")(()()))(";
	ans = longestValidParentheses(s);
	System.out.println("LongestValidParentheses demo03 result:" + ans);

	s = "()(()";
	ans = longestValidParentheses(s);
	System.out.println("LongestValidParentheses demo04 result:" + ans);
}
原文地址:https://www.cnblogs.com/fyusac/p/13234781.html