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

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

示例 1:

输入: "()"
输出: True

示例 2:

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

示例 3:

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

注意:

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

思路
看到匹配括号的,首先想到的是用栈模拟匹配,常规没有*符号情况下,代码可以这样写:

public static boolean checkValidString(String s) {LinkedList<Integer> stack = new LinkedList<>();char[] chars = s.toCharArray();int n = s.length(), i;for (i = 0; i < n; i++) {if (chars[i] == '(') {stack.offerLast(i);} else if (chars[i] == ')') {if (!stack.isEmpty()) {stack.removeLast();} else {return false;}}}return stack.isEmpty();
}

字符串中增加了*号,可以变换成() 以及空格,这样一个栈肯定是不行了。增加一个栈来记录*号呢?

计算过程为:

  1. 如果遇到左括号,则将当前下标存入左括号栈。
  2. 如果遇到星号,则将当前下标存入星号栈。
  3. 如果遇到右括号,则需要有一个左括号或星号和右括号匹配,由于星号也可以看成右括号或者空字符串,因此当前的右括号应优先和左括号匹配,没有左括号时和星号匹配:
    • 如果左括号栈不为空,则从左括号栈弹出栈顶元素;
    • 如果左括号栈为空且星号栈不为空,则从星号栈弹出栈顶元素;
    • 如果左括号栈和星号栈都为空,则没有字符可以和当前的右括号匹配,返回 false。

最后如果stackA 和 stackB 还有剩余,再根据符号下标进行比较:

  1. 左括号下标大于星号下标,返回false

具体过程请看代码

public static boolean checkValidString(String s) {// 记录(下标LinkedList<Integer> stackA = new LinkedList<>();// 记录*下标LinkedList<Integer> stackB = new LinkedList<>();char[] chars = s.toCharArray();int n = s.length(), i;for (i = 0; i < n; i++) {if (chars[i] == '(') {// 记录下(下标stackA.offerLast(i);} else if (chars[i] == '*') {// 记录下*下标stackB.offerLast(i);} else if (chars[i] == ')') {// 优先于(进行匹配,没有(则与*匹配,两者都没有说明不能匹配if (!stackA.isEmpty()) {stackA.removeLast();} else if (!stackB.isEmpty()) {stackB.removeLast();} else {return false;}}}while (!stackA.isEmpty() && !stackB.isEmpty()) {Integer a = stackA.removeLast();Integer b = stackB.removeLast();// 如果(在*前,不能匹配if (a > b) {return false;}}// 最后根据(的情况进行判断,有剩余则说明存在(不能被匹配return stackA.isEmpty();
}

LeetCode 678 有效的括号字符串,常规栈思路相关推荐

  1. LeetCode 678. 有效的括号字符串(栈)

    1. 题目 给定一个只包含三种字符的字符串:( ,) 和 *,写一个函数来检验这个字符串是否为有效字符串.有效字符串具有如下规则: 任何左括号 ( 必须有相应的右括号 ). 任何右括号 ) 必须有相应 ...

  2. leetcode 678 有效的括号字符串

    给定一个只包含三种字符的字符串:( ,) 和 *,写一个函数来检验这个字符串是否为有效字符串.有效字符串具有如下规则: 任何左括号 ( 必须有相应的右括号 ). 任何右括号 ) 必须有相应的左括号 ( ...

  3. LeetCode 678. 有效的括号字符串

    传送门:https://leetcode-cn.com/problems/valid-parenthesis-string 题目描述: 给定一个只包含三种字符的字符串:( ,) 和 *,写一个函数来检 ...

  4. 678. 有效的括号字符串

    678. 有效的括号字符串 给定一个只包含三种字符的字符串:( ,) 和 *,写一个函数来检验这个字符串是否为有效字符串.有效字符串具有如下规则: 任何左括号 ( 必须有相应的右括号 ). 任何右括号 ...

  5. LeetCode 2116. 判断一个括号字符串是否有效(栈)

    文章目录 1. 题目 2. 解题 1. 题目 一个括号字符串是只由 '(' 和 ')' 组成的 非空 字符串. 如果一个字符串满足下面 任意 一个条件,那么它就是有效的: 字符串为 (). 它可以表示 ...

  6. 字符串专题-LeetCode:剑指 Offer 58 - II. 左旋转字符串、LeetCode 459.重复的子字符串、 代码思路和注意点

    文章目录 一.剑指 Offer 58 - II. 左旋转字符串 二.LeetCode 459.重复的子字符串 一.剑指 Offer 58 - II. 左旋转字符串 思路: 预留出n个字符空间s.res ...

  7. leetcode 678. Valid Parenthesis String | 678. 有效的括号字符串(带缓存的暴力递归)

    题目 https://leetcode.com/problems/valid-parenthesis-string/ 题解 带缓存的暴力递归,非常挫.用一个 string 模拟 stack,方便缓存记 ...

  8. 【Java】LeetCode 20 有效的括号 (运用数据结构:栈 解题)

    题目: 给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效. 有效字符串需满足: 左括号必须用相同类型的右括号闭合. 左括号必须以正确的顺序闭合. 解题 ...

  9. 算法训练Day11|LeetCode 20. 有效的括号、1047. 删除字符串中的所有相邻重复项、150. 逆波兰表达式求值

    题目链接:20. 有效的括号 第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false 第二种情况:遍历字符串匹配的过程中,发现栈里没有要匹配的字 ...

最新文章

  1. 【Linux】43.ubuntu18.04安装搜狗输入法不能正常使用
  2. 开始使用vue.js
  3. Zookeeper的概述
  4. 西媒盘点:历史不该遗忘的七位女数学家
  5. 【树莓派搭建个人网站】花生壳内网穿透
  6. java线程 锁_Java多线程(二) 多线程的锁机制
  7. Android iw 使用方法
  8. css 使用本地字体
  9. 这三款曾红极一时的软件,现已风光不再,而遭嫌弃的它成了香饽饽
  10. Python数据库编程
  11. 最长回文子串 马拉车算法
  12. Redis可视化客户端
  13. 海康威视查询序列号 紫盘
  14. 【JavaScript】数组方法应用自测例题
  15. 折叠屏显示器比折叠屏手机更有价值
  16. 微信红包c语言程序,C语言 微信红包
  17. Python基本语法,让我们轻松入门学习Python!
  18. NX上配置TLD的环境---对opencv的版本没有要求
  19. tomcat从零开始配置https
  20. 工字型钢弹性截面模量计算公式_截面模量的计算公式是什么?

热门文章

  1. 用代码证明自己闲的蛋疼(一)——cmd闪瞎狗眼
  2. 华为机试——求int型正整数在内存中存储时1的个数
  3. 【STL学习】自己动手C++编程实现hash table(散列表)
  4. http库cookiejar模块
  5. dj电商-需求分析-商品模块
  6. php脚本定时更新商品列表
  7. maatkit使用总结
  8. MySQL-MySQL数据类型及占用字节数
  9. 理解Java操作数据库原理
  10. 亲测可用,超详细RabbitMQ消息队列集群配置