题目
给定一个只包括 ‘(‘,’)’,’{‘,’}’,’[‘,’]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
示例:{()},()[],都是有效匹配,{()]为无效匹配
方法:栈
思路
由题目可以知道,要有效匹配,就得左括号和右括号匹配,后出现的左括号总是和先出现的右括号匹配,遵循后进先出的特点,而这一特点就和栈的特点类似
代码实现
import java.util.*;
public class test{ public static void main(String[] args) { Solution solution = new Solution(); System.out.println(solution.isVaild("{[]}")); } }
class Solution{ public boolean isVaild(String s){ int n = s.length(); if(n % 2 == 1){ return false; }
Map<Character,Character> brackets = new HashMap<Character, Character>(){ { put(')' , '('); put(']' , '['); put('}' , '{'); } };
Deque<Character> stack = new LinkedList<Character>(); for(int i = 0; i < n; i++){ char ch = s.charAt(i); if(brackets.containsKey(ch)){ if(stack.isEmpty() || stack.peek() != brackets.get(ch)){ return false; } stack.pop(); }else { stack.push(ch); } } return stack.isEmpty(); } }
|
算法主体
Java(1)
class Solution{ public boolean isVaild(String s){ int n = s.length(); if(n % 2 == 1){ return false; }
Map<Character,Character> brackets = new HashMap<Character, Character>(){ { put(')' , '('); put(']' , '['); put('}' , '{'); } };
Deque<Character> stack = new LinkedList<Character>(); for(int i = 0; i < n; i++){ char ch = s.charAt(i); if(brackets.containsKey(ch)){ if(stack.isEmpty() || stack.peek() != brackets.get(ch)){ return false; } stack.pop(); }else { stack.push(ch); } } return stack.isEmpty(); } }
|
note
:建立Hashmap
,用Deque
接口实现Linkedlist
类作为栈,charAt()
方法返回索引处的 char 值,会另开文章总结
Java(2)
针对此题还有一种快速的方法,利用 foreach 迭代来遍历字符串数组
class Solution { public boolean isVaild(String s) { Stack<Character> stack = new Stack<Character>(); for (char c : s.toCharArray()) { if (c == '(') stack.push(')'); else if (c == '{') stack.push('}'); else if (c == '[') stack.push(']'); else if (stack.isEmpty() || stack.pop() != c) return false; } return stack.isEmpty(); } }
|
C
char pairs(char a) { if (a == '}') return '{'; if (a == ']') return '['; if (a == ')') return '('; return 0; }
bool isValid(char* s) { int n = strlen(s); if (n % 2 == 1) { return false; } int stk[n + 1], top = 0; for (int i = 0; i < n; i++) { char ch = pairs(s[i]); if (ch) { if (top == 0 || stk[top - 1] != ch) { return false; } top--; } else { stk[top++] = s[i]; } } return top == 0; }
|
C 和 Java 的原理都差不多,都是要把左括号入栈,右括号作为跳板,重点就是要与栈顶元素的匹配。观察两种语言的算法实现还是很有趣的。
复杂度
时间复杂度:O(n),因为要遍历字符串 s,其中 n 是字符串 s 的长度。
空间复杂度:O(n+∣Σ∣),其中 Σ 表示字符集,本题中字符串只包含 6 种括号,∣Σ∣=6。栈中的字符数量为 O(n),而哈希表使用的空间为 O(∣Σ∣),相加即可得到总空间复杂度。