> 文档中心 > 【LeetCode】20-有效的括号

【LeetCode】20-有效的括号


20-有效的括号

题目描述

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。

示例

示例一:输入:s = "()"输出:true示例二:输入:s = "()[]{}"输出:true示例三:输入:s = "(]"输出:false示例四:输入:s = "([)]"输出:false示例五:输入:s = "{[]}"输出:true

提示

1 <= s.length <= 104s 仅由括号 '()[]{}' 组成

题解

由题目可知,通过输入一个仅有括号组成的字符串,返回输入的字符串中括号是否有效,总共涉及到()[]{}三种类型的括号。

括号有效的判断依据如下:

  1. 每一个左括号必须要有对应的有括号,例如()[]{}就是有效的,而(]则是无效的。
  2. 括号必须按照顺序成对,也就是说按从左到右的顺序,在字符串中出现的第一个右括号必须与它前面出现的最后一个左括号成对,以此类推。

例如有字符串s = ([]){},下标为i,从左往右依次遍历,使用字符串 left 来记录出现的左括号序列。

i = 0 时,left = "("

i = 1 时,left = "(["

i = 2 时,碰到右括号],可以和左括号序列中最后一位[成对,则[]相互抵消,这时候 left = (

i = 3 时,碰到右括号),可以和左括号序列中最后一位(成对,则()相互抵消,这时候 left = ""

i = 4 时,left = "{"

i = 5时,碰到右括号},可以和左括号序列中最后一位{成对,则{}相互抵消,这时候 left = ""

当遍历完字符串后,表示左括号序列的 left 为空时,则表示字符串 s 是有效的。 如果在遍历的过程中出现的右括号和左括号序列的最后一位无法成对,则可以直接返回 false,没有再继续遍历的必要。

通过上面的分析,可以发现原理其实很简单,但是如果在写代码的过程中使用一个字符串来表示左序列,在遍历的过程中就需要不断的拼接字符串或切割字符串,这样的效率是很低的。这时候有一个数据结构就派上了用场,那就是栈,由于栈有先进后出的特点,也完美的符合在遍历过程中每一次碰到右括号时与左括号序列的最后一个做比较的场景。 同时利用栈的 push 方法朝栈内添加左括号,碰到右括号时使用 pop 方法弹出栈顶元素(左括号序列的最后一个元素)与右括号进行匹配。

代码如下:

public boolean isValid(String s) {  Stack<Character> stack = new Stack<>();  for (int i = 0; i < s.length(); i++) {    char c = s.charAt(i);    if (c == '(' || c == '[' || c == '{') {      stack.push(c);    }    if (c == ')' && (stack.isEmpty() || stack.pop() != '(')) {      return false;    }    if (c == ']' && (stack.isEmpty() || stack.pop() != '[')) {      return false;    }    if (c == '}' && (stack.isEmpty() || stack.pop() != '{')) {      return false;    }  }  return stack.isEmpty();}

代码解析

使用 for 循环遍历字符串,当字符是(、[、{三个中的某一个时,将其压入到栈中,当字符是)、]、}三个中的某一个时取出栈顶元素进行匹配,如果无法成对,则直接返回 false,最后再判断栈中是否为空,如果为空,则返回 true,否则返回 false。

关注专栏持续更新
公众号:良猿