20.有效括号

方法一  栈

 1 public static boolean isValid(String s) {
 2         int n = s.length();
 3         //有效字符串的长度一定为偶数,因此如果字符串的长度为奇数,我们可以直接返回 \text{False}False,省去后续的遍历判断过程
 4         if (n % 2 == 1) {
 5             return false;
 6         }
 7         //为了快速判断括号的类型,我们可以使用哈希表存储每一种括号。哈希表的键为右括号,值为相同类型的左括号。
 8         Map<Character, Character> pairs = new HashMap<Character, Character>() {{
 9             put(')', '(');
10             put(']', '[');
11             put('}', '{');
12         }};
13         //java把栈封装在了linkedlist中的deque接口里面
14         Deque<Character> stack = new LinkedList<>();
15         for (int i = 0; i < n; i++) {
16             char ch = s.charAt(i);
17             if (pairs.containsKey(ch)) {
18                 //如果是右括号,如果栈为空(说明没有对应的左括号)或者如果栈顶的左括号和对应的左括号不同的话,不符
19                 if (stack.isEmpty() || !stack.peek().equals(pairs.get(ch))) {
20                     return false;
21                 }
22                 //栈顶的左括号和对应的左括号相同,出栈
23                 stack.pop();
24             } else {
25                 //如果是左括号,入栈
26                 stack.push(ch);
27             }
28         }
29         //在遍历结束后,如果栈中没有左括号,说明我们将字符串 ss 中的所有左括号闭合
30         return stack.isEmpty();
31     }

栈中方法讲解

push()操作在堆栈的顶部加入一个元素。

pop()操作相反, 在堆栈顶部移去一个元素, 并将堆栈的大小减一。

peek()是返回栈顶的元素但不移除它。但pop方法是会移除的。

复杂度分析

时间复杂度:O(n)O(n),其中 nn 是字符串 ss 的长度。

空间复杂度:O(n + |\Sigma|)O(n+∣Σ∣),其中 \SigmaΣ 表示字符集,本题中字符串只包含 66 种括号,|\Sigma| = 6∣Σ∣=6。栈中的字符数量为 O(n)O(n),而哈希表使用的空间为 O(|\Sigma|)O(∣Σ∣),相加即可得到总空间复杂度。

方法二  字符串替换

 1  public static boolean isValid(String s) {
 2         int length;
 3         do {
 4             length = s.length();
 5             s = s.replace("()", "")
 6                     .replace("{}", "")
 7                     .replace("[]", "");
 8         } while (length != s.length());
 9         return s.length() == 0;
10     }

时间复杂度 不好判断,是O(n^2/2),比起用stack的话,时间复杂度要差点

 

posted @ 2021-05-14 17:59  JustJavaIt  阅读(60)  评论(0编辑  收藏  举报