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的话,时间复杂度要差点
希望本文章对您有帮助,您的转发、点赞是我的创作动力,十分感谢。更多好文推荐,请关注我的微信公众号--JustJavaIt