题目描述

D2BCF617-6F60-4273-9DD5-4A706CEBB0BB_1_201_a.jpeg

题目链接

https://leetcode.cn/problems/valid-parentheses/

思路

判断括号的有效性可以使用「栈」这一数据结构来解决,因为栈先入后出特点恰好与括号排序特点一致。

我们遍历给定的字符串【20】有效的括号 - 图2。当我们遇到一个左括号时,我们会期望在后续的遍历中,有一个相同类型的右括号将其闭合。由于后遇到的左括号要先闭合,因此我们可以将这个左括号放入栈顶。当我们遇到一个右括号时,我们需要将一个相同类型的左括号闭合。此时,我们可以取出栈顶的左括号并判断它们是否是相同类型的括号。如果不是相同的类型,或者栈中并没有左括号,那么字符串【20】有效的括号 - 图3无效,返回【20】有效的括号 - 图4
baa8829ac398e665eb645dca29eadd631e2b337e05022aa5a678e091471a4913-20.gif
为了快速判断括号的类型,我们可以使用哈希表存储每一种括号。哈希表的键为右括号,值为相同类型的左括号。

在遍历结束后,如果栈中没有左括号,说明我们将字符串【20】有效的括号 - 图6中的所有左括号闭合,此时返回【20】有效的括号 - 图7,否则返回【20】有效的括号 - 图8。注意到有效字符串的长度一定为偶数,因此如果字符串的长度为奇数,我们可以直接返回【20】有效的括号 - 图9,省去后续的遍历判断过程。

代码实现

  1. public boolean isValid(String s) {
  2. // 长度为奇数直接退出
  3. if (s.length() % 2 == 1) {
  4. return false;
  5. }
  6. Map<Character, Character> pairs = new HashMap<Character, Character>() {{
  7. put(')', '(');
  8. put(']', '[');
  9. put('}', '{');
  10. }};
  11. Stack<Character> stack = new Stack<>();
  12. for (char c : s.toCharArray()) {
  13. // 如果是右括号
  14. if (pairs.containsKey(c)) {
  15. // 判断能否与栈顶的左括号相匹配
  16. if (stack.isEmpty() || stack.peek() != pairs.get(c)) {
  17. return false;
  18. }
  19. stack.pop();
  20. } else {
  21. stack.push(c);
  22. }
  23. }
  24. return stack.isEmpty();
  25. }

实际上,由于括号的种类比较少,只有【20】有效的括号 - 图10种括号,我们可以不使用哈希表,而是直接进行判断。这样空间复杂度可以降到【20】有效的括号 - 图11,代码实现如下:

  1. public boolean isValid(String s) {
  2. if (s == null || s.length() < 2) {
  3. return false;
  4. }
  5. Stack<Character> stack = new Stack<>();
  6. for (char c : s.toCharArray()) {
  7. if (stack.empty()) {
  8. stack.push(c);
  9. } else {
  10. char stackTop = stack.peek();
  11. if ((stackTop == '(' && c == ')') || (stackTop == '{' && c == '}') || (stackTop == '[' && c == ']')) {
  12. stack.pop();
  13. } else {
  14. stack.push(c);
  15. }
  16. }
  17. }
  18. return stack.empty();
  19. }

复杂度分析

  • 时间复杂度:【20】有效的括号 - 图12,其中【20】有效的括号 - 图13是字符串【20】有效的括号 - 图14的长度。
  • 空间复杂度:【20】有效的括号 - 图15,其中【20】有效的括号 - 图16表示字符集,本题中字符串只包含【20】有效的括号 - 图17种括号,【20】有效的括号 - 图18。栈中的字符数量为【20】有效的括号 - 图19,而哈希表使用的空间为【20】有效的括号 - 图20,相加即为总空间复杂度。