小念子

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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

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

 

解答

1、使用两个栈分别存储左括号和星号的下标,leftBracketStack和starStack。遇到右括号,优先与左括号栈顶抵消,若左括号为空,才与星栈顶抵消。

2、最后若leftBracketStack和starStack不为空,再进行处理。如果左括号栈顶大于星栈顶,类似*(,则无法抵消,返回false;如果左括号栈顶小于星栈顶,类似(*,则可以抵消,同时弹出栈顶。往下处理知道其中一个(两个)为空

 

3、最后若leftBracketStack不为空,starStack为空,没有多余的星号与左括号进行匹配,返回false。否则返回true。

    public boolean checkValidString(String s) {
        if (s == null || s.length() == 0) {
            return true;
        }
        Stack<Integer> leftBracketStack = new Stack<>();
        Stack<Integer> starStack = new Stack<>();
        for (int i = 0; i < s.length(); ++i) {
            char ch = s.charAt(i);
            if (ch == '(') {
                leftBracketStack.push(i);
            } else if (ch == '*') {
                starStack.push(i);
            } else {
                if (leftBracketStack.isEmpty() && starStack.isEmpty()) {
                    return false;
                } else if (!leftBracketStack.isEmpty()) { // 优先匹配左括号
                    leftBracketStack.pop();
                } else { // 没有左括号才去匹配星号
                    starStack.pop();
                }
            }
        }
        // 处理剩余的左括号和星号。从后往前,从栈顶开始处理
        while (!leftBracketStack.isEmpty() && !starStack.isEmpty()) {
            if (leftBracketStack.peek() > starStack.peek()) { // 左括号在星号后面,比如*(,不符合
                return false;
            }
            // 否则左括号在星号前面,比如(*,符合,弹出继续向前匹配
            leftBracketStack.pop();
            starStack.pop();
        }
        if (!leftBracketStack.isEmpty()) { // 最后剩余左括号,不符合
            return false;
        }
        return true;
    }

 

posted on 2020-11-21 11:37  小念子  阅读(113)  评论(0编辑  收藏  举报