LeetCode 刷题系列 678有效的括号字符串

题目描述

//给定一个只包含三种字符的字符串:( ,) 和 ,写一个函数来检验这个字符串是否为有效字符串。有效字符串具有如下规则:
//
//
// 任何左括号 ( 必须有相应的右括号 )。
// 任何右括号 ) 必须有相应的左括号 ( 。
// 左括号 ( 必须在对应的右括号之前 )。
// * 可以被视为单个右括号 ) ,或单个左括号 ( ,或一个空字符串。
// 一个空字符串也被视为有效字符串。
//
//
// 示例 1:
//
//
//输入: “()”
//输出: True
//
//
// 示例 2:
//
//
//输入: "(
)"
//输出: True
//
//
// 示例 3:
//
//
//输入: “(*))”
//输出: True
//

主要思路

  1. 贪心地去掉所有的右括号
    为什么是贪心呢?优先使用左括号匹配。只有当左括号没有的时候才使用星号去删除。
  2. 计算剩余的左括号及星号
    ((**符合
    *(( 不符合。
    基于上面分析,可以使用两个栈。一个用于存放“(",另外一个存放

    由于使用2个栈。因此栈里面存放的是index,而不是值。通过这种方式来知道相对顺序。
    如果只使用一个栈也可以,只是要处理第一步贪心的地方。处理略显麻烦。

代码

public class P678ValidParenthesisString {

    @Test
    public void testP678ValidParenthesisString() {
        Solution solution = new P678ValidParenthesisString().new Solution();
        assertThat("1", solution.checkValidString("()"), CoreMatchers.is(true));
        assertThat("1", solution.checkValidString("(*)"), CoreMatchers.is(true));
        assertThat("1", solution.checkValidString("(*))"), CoreMatchers.is(true));
        assertThat("1", solution.checkValidString("))***"), CoreMatchers.is(false));
    }

    //leetcode submit region begin(Prohibit modification and deletion)
    class Solution {
        public boolean checkValidString(String s) {

            Deque<Integer> deque = new LinkedList<>();
            Deque<Integer> assi = new LinkedList<>();
            for (int i = 0; i < s.length(); i++) {
                char c = s.charAt(i);
                if (c == '(') {
                    deque.addLast(i);
                } else if (c == ')') {
                    //优先使用左括号来消除
                    if (!deque.isEmpty()) {
                        deque.pollLast();

                    } else if (!assi.isEmpty()) {
                        //左括号用完的时候使用*.
                        assi.pollLast();
                    } else {
                        // 左括号、*都使用完了,说明此时只有右括号了,肯定匹配不上。直接返回。
                        return false;
                    }

                } else {
                    assi.addLast(i);
                }

            }
            // 走到这里说明右括号已经处理完了。处理其余的左括号与*
            //((**这种情况是能够处理的。

            while (!deque.isEmpty() && !assi.isEmpty()) {
                // **((这种情况不不可能成功的,直接返回。
                if (assi.pollLast() < deque.pollLast()) {
                    return false;
                }
            }
            // 最后如果是(还有剩余。直接返回。
            // 如果是*还有剩余,是符合要求的。
            return deque.isEmpty();

        }
    }
//leetcode submit region end(Prohibit modification and deletion)

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值