算法学习笔记(29)-字符串有效括号问题

/**
 * @version 0.1
 * @since 2021/10/24
 * @author Void Bug
 *
 * <br>字符串类问题<br>
 * 题目:已知一个字符串都是由左括号(和右括号)组成,判断该字符串是否是有效的括号组合。
 * 例子:
 * 有效的括号组合:()(),(()),(()())
 * 无效的括号组合:(,()),((),()(()
 * 题目进阶:
 * 已知一个字符串都是由左括号(和右括号)组成,返回最长有效括号子串的长度。
 */
public class Problem_01_ParenthesesProblem {
    
    

    /**
     * O(n)
     * 当 string 是一个空串或者他的长度小于0 时候,说明这个串是空的,返回false
     * 当我们遍历数组时候,发现 ( 元素时候,我们统计到的数据 +1 ,当发现 ) 元素时候,我们统计数据 -1
     * 当 便利字符串是发现遍历到的数组元素不是 ( 或者 ) 时候,返回false
     * 当遍历时候发现 () 不是成对出现时候,返回 false
     * 当遍历发现 ( 时候,我们继续遍历看是否 存在相匹配的 ) 元素,如果循环完了,发现 我们统计的个数不是 0 时候我们就可以判定,返回false
     * 当统计次数又变为 0 时候,我们返回 true
     * @param string 传递的 String 字符串
     * @return 返回是否是合理的字符串
     */
    private static boolean isValue(String string){
    
    
        if (string == null || string.length() == 0) {
    
    
            return false;
        }
        char[] chars = string.toCharArray();
        int start = 0;
        for (char aChar : chars) {
    
    
            if (aChar != ')' && aChar != '(') {
    
    
                return false;
            }
            if (aChar == ')' && --start < 0) {
    
    
                return false;
            }
            if (aChar == '(') {
    
    
                start++;
            }
        }
        return start == 0;
    }

    /**
     * O(n)
     * 当 string 是一个空串或者他的长度小于0 时候,说明这个串是空的,返回 0
     * 从下标为1的元素开始查找,到length-1 ,去进行寻找
     * 假设我们知道 m~n-1上的最大个数,我们只需要先去看下前面的元素m-1是否在数组中是否存在
     * 如果存在的话,我们只需要去看 m-1 和 n 这两个是否是匹配的即可
     * 注意:针对 ()(()()) 数据时候我们输出的是 8,不是6
     * @param string 传递的 String 字符串
     * @return 返回最长有效括号子串的长度
     */
    private static int MaxLengths(String string){
    
    
        if (string == null || string.length() == 0) {
    
    
            return 0;
        }

        char[] chars = string.toCharArray();
        int[] dp = new int[chars.length];
        int pre,res=0; // res 最长有效括号子串的长度
        for (int i = 1; i < chars.length; i++) {
    
    
            if (chars[i] == ')') {
    
    
                // 找到与其配对的 ( 符号,如果>=0 说明前面数组还有指定长度的元素个数,当 <0 时候前面就没有了,就没必要找了
                // > 0 时候说明是存在
                // = 0 时候说明没有了
                pre= i- dp[i-1]-1;
                if (pre>=0 && chars[pre]=='(') {
    
    
                    // 通过之前的数据来快速迭代上一次的数据
                    dp[i] = dp[i - 1] + 2+(pre>0? dp[pre - 1] : 0);
                }
            }
            res= Math.max(res,dp[i]);
        }
        return res;
    }

    public static void main(String[] args) {
    
    
        String str1 = "((())())";
        System.out.println(isValue(str1));
        System.out.println(MaxLengths(str1));

        String str2 = "(())(()(()))";
        System.out.println(isValue(str2));
        System.out.println(MaxLengths(str2));

        String str3 = "())(()()(";
        System.out.println(isValue(str3));
        System.out.println(MaxLengths(str3));

    }
}

Guess you like

Origin blog.csdn.net/qq_45205390/article/details/120951583