zoukankan      html  css  js  c++  java
  • Medium | LeetCode 678. 有效的括号字符串 | 贪心

    678. 有效的括号字符串

    给定一个只包含三种字符的字符串:*,写一个函数来检验这个字符串是否为有效字符串。有效字符串具有如下规则:

    1. 任何左括号 ( 必须有相应的右括号 )
    2. 任何右括号 ) 必须有相应的左括号 (
    3. 左括号 ( 必须在对应的右括号之前 )
    4. * 可以被视为单个右括号 ) ,或单个左括号 ( ,或一个空字符串。
    5. 一个空字符串也被视为有效字符串。

    示例 1:

    输入: "()"
    输出: True
    

    示例 2:

    输入: "(*)"
    输出: True
    

    示例 3:

    输入: "(*))"
    输出: True
    

    注意:

    1. 字符串大小将在 [1,100] 范围内。

    解题思路

    方法一:贪心

    先考虑最简单的情况, 在没有*号, 只包含左右括号的字符串。

    在这种情况下, 只需要从左到右扫描, 记录左括号比右括号多的个数。在遍历过程, 只要这个数>=0, 在遍历时, 结果是0, 那么就说明这个字符串时有效的。

    现在在其中加入* 号, 增加了不确定因素。

    所以左括号比右括号多出的个数也是不确定的。但是核心的思想还是一样的,只要这个数>=0, 并且最终时等于0就可以了。所以可以在记录这个数时, 不是记录一个确切的数, 而是记录这个数的区间。只要在在扫描的过程中, 区间最大值不小于0, 区间结果值包含0, 就说明是正确的。

    算法如下:

    在处理字符串中的当前字符时,让 lo、hi 分别为可能的最小和最大左括号数。
    如果我们遇到左括号c == '(',那么 lo++,若遇到右括号,则 lo--。如果我们遇到 * 号且可以转换成左括号c != ')',则 hi++,否则我们转换成右括号,所以 hi--。如果 hi<0 ,那么无论我们选择什么,当前情况都无法生成有效的括号。而且,左括号不能小于0。最后,我们应该检查一下是否可以有 0 个左括号。

    public boolean checkValidString(String s) {
        int minLeftReminded = 0, maxLeftReminded = 0;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            switch (c) {
                case '(':
                    minLeftReminded++;
                    maxLeftReminded++;
                    break;
                case ')':
                    minLeftReminded--;
                    maxLeftReminded--;
                    break;
                case '*':
                    // * 可以代表 )
                    minLeftReminded--;
                    // * 可以代表 (
                    maxLeftReminded++;
                    break;
                default:
                    break;
            }
            // 在扫描过程中, 如果出现左括号比右括号少, 则直接返回
            if (maxLeftReminded < 0) {
                return false;
            }
            // 在扫描过程中, 如果出现*号表示)时, 左括号比右括号少, 那么这个*号就不能表示), 
            if (minLeftReminded < 0) {
                minLeftReminded = 0;
            }
        }
        return minLeftReminded <= 0;
    }
    
  • 相关阅读:
    【转】 java中Class对象详解和类名.class, class.forName(), getClass()区别
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
    107. Binary Tree Level Order Traversal II
    109. Convert Sorted List to Binary Search Tree
    108. Convert Sorted Array to Binary Search Tree
    110. Balanced Binary Tree
    STL容器迭代器失效问题讨论
    113. Path Sum II
    112. Path Sum
  • 原文地址:https://www.cnblogs.com/chenrj97/p/14621780.html
Copyright © 2011-2022 走看看