leetcode 32 ---- 动态规划、栈、索引(困难) :最长有效括号(java)

1.   问题给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。

示例1

输入:"(()"      输出:2

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

示例2

输入:"()(()"      输出:2

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

示例3

输入:"()(())"      输出:6

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

示例4

输入:")()())"      输出:4

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

2.   问题分析:

方法1:利用栈的思想,记录索引,对索引进行处理来得到最长有效括号子串数目。

举例:s="())))((())"   设 i s的索引, 数组stack[-1,...],长度为(s.length+1),top为stack的索引(类似于栈顶索引,刚开始学java,栈不会使用,用数组代替),初始化时top=0。遍历s如下图所示:

算法分为两步走:

         a:如果 s[i] == "(" ,top++,把 i 存储到stack[top]数组中  

         b:如果  s[i] == ")",top--,然后对top进行条件判断:

                                 如果top<0,top++,stack[top]=i

                                 否则,Max_len = max( Max_len,  i-stack[top] )     

方法2: 使用动态规划的思想

dp[i]等于 s 中长度为 i 的字符串的最长的有效括号数量,

如s="()(())",dp=[0 2 0 0 2 6 ]。

观察到一个现象:s[0]与s[1]配对,s[3]与s[4]配对,s[2]与s[5]配对,(待续。。。)

3.   方法1 java程序:
 

class Solution {
    public int longestValidParentheses(String s) {
		
		//String s ="()))))(())";
		int top = 0;                            // stack[]的索引  相当于栈顶索引
		int [] stack = new int [s.length()+1];  // 申请一个和(s+1)一样大的数组
		stack[0] = -1;                          // 第一个值赋值为-1
		int max_len = 0;                        // 存储最长有效字括号
		int leth =0;                            // 中间变量
		
		// 遍历s中的每一个元素
		for (int i=0;i<s.length();i++){
			
			// 如果s[i]中的元素为"(",将位置 i 存入stack中 
			if (s.charAt(i) == '('){
				stack[++top] =  i;
			}
			//否则,
			else{
				// top索引减1
				top--;
				// top<0时,top++,并存储坐标i
				if (top<0){
					stack[++top] =  i;
				}
				// top >= 0时,s当前位置i减去top指向的stack中的值
				else{
					leth = i - stack[top];
					// 和上次最大值进行比较,最大值赋给max_len
					if (max_len<leth){
						max_len = leth;
					}
				}
			}
		}

		System.out.println("最长有效括号为:"+max_len);
			
	}

}

4.   方法2 java程序:

public static int longestValidParentheses(String s) {
        if (s == null || s.length() == 0)
            return 0;
        int result = 0;
        int[] dp = new int[s.length()];
		
        for (int i = 0; i < s.length(); i++) {
			
            if (i == 0)
                continue;
			
            if (s.charAt(i) == ')') {
				
                if (s.charAt(i - 1) == '(') {
                    dp[i] = 2 + ( i - 2 >= 0 ? dp[i - 2] : 0 );
                } else if (i - dp[i - 1] - 1 >= 0 && s.charAt(i - dp[i - 1] - 1) == '(') {
                    dp[i] = dp[i - 1] + 2 + (i - dp[i - 1] - 2 >= 0 ? dp[i - dp[i - 1] - 2] : 0);
                }
				result = result>dp[i] ? result:dp[i];     // result = Integer.max(result, dp[i]);   
            }
        }
        return result;
    }

猜你喜欢

转载自blog.csdn.net/weixin_39781462/article/details/83148493