括号相关问题
20. 有效的括号
给定一个只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串 s
,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
示例 1:
**输入:**s = “()”
**输出:**true
示例 2:
**输入:**s = “()[]{}”
**输出:**true
示例 3:
**输入:**s = “(]”
**输出:**false
示例 4:
**输入:**s = “([])”
**输出:**true
提示:
1 <= s.length <= 10^4
s
仅由括号 '()[]{}'
组成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Solution { public boolean isValid(String s) { char cs[] = s.toCharArray(); Map<Character, Character> map = new HashMap<>(); map.put(')', '('); map.put('}', '{'); map.put(']', '['); Deque<Character> stack = new LinkedList<>(); for (char c : cs) { Character match = map.get(c); if (match == null) { stack.push(c); } else { if (!stack.isEmpty() && stack.peek().equals(match)) { stack.pop(); } else { return false; } } } return stack.isEmpty(); } }
|
22. 括号生成
数字 n
代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例 1:
1 2
| 输入:n = 3 输出:["((()))","(()())","(())()","()(())","()()()"]
|
示例 2:
提示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class Solution { ArrayList<String> res = new ArrayList<>(); public ArrayList<String> generateParenthesis (int n) { dfs(n, n, ""); return res; } public void dfs(int left, int right, String s) { if (left == 0 && right == 0) { res.add(s); return; } if (left > 0) dfs(left-1, right, s+"("); if (right > 0 && right > left) dfs(left, right-1, s+")"); } }
|
32. 最长有效括号
给你一个只包含 '('
和 ')'
的字符串,找出最长有效(格式正确且连续)括号子串的长度。
示例 1:
1 2 3
| 输入:s = "(()" 输出:2 解释:最长有效括号子串是 "()"
|
示例 2:
1 2 3
| 输入:s = ")()())" 输出:4 解释:最长有效括号子串是 "()()"
|
示例 3:
提示:
0 <= s.length <= 3 * 10^4
s[i]
为 '('
或 ')'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class Solution { public int longestValidParentheses(String s) { char[] cs = s.toCharArray(); int n = cs.length; Deque<Integer> stack = new LinkedList<>(); int res = 0, pre = -1; for (int i = 0; i < n; i++) { char c = cs[i]; if (c == '(') { stack.push(i); } else { if (!stack.isEmpty()) { stack.pop(); int left = pre; if (!stack.isEmpty()) left = stack.peek(); res = Math.max(res, i - left); } else { pre = i; } } } return res; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Solution { public int longestValidParentheses(String s) { char[] cs = s.toCharArray(); int n = cs.length; int[] f = new int[n+1]; for (int i = 1; i < n; i++) { if (cs[i] == '(') continue; if (cs[i-1] == '(') { f[i+1] = f[i-1] + 2; } else { if (i-f[i]-1 >= 0 && cs[i-f[i]-1] == '(') { f[i+1] = f[i] + 2 + f[i-f[i]-1]; } } } return Arrays.stream(f).max().getAsInt(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class Solution { public int longestValidParentheses(String s) { char[] cs = s.toCharArray(); int n = cs.length; int res = 0, left = 0, right = 0; for (int i = 0; i < n; i++) { if (cs[i] == '(') left++; else right++; if (left == right) res = Math.max(res, left + right); if (left < right) { left = 0; right = 0; } } left = 0; right = 0; for (int i = n-1; i >= 0; i--) { if (cs[i] == '(') left++; else right++; if (left == right) res = Math.max(res, left + right); if (left > right) { left = 0; right = 0; } } return res; } }
|
301. 删除无效的括号
给你一个由若干括号和字母组成的字符串 s
,删除最小数量的无效括号,使得输入的字符串有效。
返回所有可能的结果。答案可以按 任意顺序 返回。
示例 1:
1 2
| 输入:s = "()())()" 输出:["(())()","()()()"]
|
示例 2:
1 2
| 输入:s = "(a)())()" 输出:["(a())()","(a)()()"]
|
示例 3:
提示:
1 <= s.length <= 25
s
由小写英文字母以及括号 '('
和 ')'
组成
s
中至多含 20
个括号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| class Solution { List<String> res = new ArrayList<>(); int maxLen = 0; public List<String> removeInvalidParentheses(String s) { char[] cs = s.toCharArray(); dfs(cs, 0, 0, ""); return res; } public void dfs(char[] cs, int cur, int balance, String s) { int n = cs.length; if (balance < 0) return; if (cur == n) { if (balance == 0) { if (s.length() > maxLen) { maxLen = s.length(); res.clear(); } if (s.length() == maxLen && !res.contains(s)) res.add(s); } return; } if (cs[cur] == '(' || cs[cur] == ')') dfs(cs, cur+1, balance, s); if (cs[cur] == '(') { dfs(cs, cur+1, balance+1, s+"("); } else if (cs[cur] == ')') { dfs(cs, cur+1, balance-1, s+")"); } else { dfs(cs, cur+1, balance, s+cs[cur]); } } }
|
678. 有效的括号字符串
给你一个只包含三种字符的字符串,支持的字符类型分别是 '('
、')'
和 '*'
。请你检验这个字符串是否为有效字符串,如果是 有效 字符串返回 true
。
有效 字符串符合如下规则:
- 任何左括号
'('
必须有相应的右括号 ')'
。
- 任何右括号
')'
必须有相应的左括号 '('
。
- 左括号
'('
必须在对应的右括号之前 ')'
。
'*'
可以被视为单个右括号 ')'
,或单个左括号 '('
,或一个空字符串 ""
。
示例 1:
示例 2:
示例 3:
提示:
1 <= s.length <= 100
s[i]
为 '('
、')'
或 '*'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class Solution { public boolean checkValidString(String s) { char[] cs = s.toCharArray(); int min = 0, max = 0; for (char c : cs) { if (c == '(') { min++; max++; } else if (c == ')') { min--; max--; } else if (c == '*') { min--; max++; } min = Math.max(min, 0); if (max < 0) return false; } return min == 0; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Solution { public boolean checkValidString(String s) { char[] cs = s.toCharArray(); int[][][] memo = new int[101][101][101]; return dfs(cs, 0, 0, 0, memo); } public boolean dfs(char[] cs, int cur, int left, int right, int[][][] memo) { if (memo[cur][left][right] != 0) return memo[cur][left][right] == 1; int n = cs.length; if (right > left) return false; if (cur == n) return left == right; boolean res = false; if (cs[cur] == '(') res = dfs(cs, cur+1, left+1, right, memo); else if (cs[cur] == ')') res = dfs(cs, cur+1, left, right+1, memo); else res = dfs(cs, cur+1, left+1, right, memo) || dfs(cs, cur+1, left, right+1, memo) || dfs(cs, cur+1, left, right, memo); memo[cur][left][right] = res ? 1 : 2; return res; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| class Solution { public boolean checkValidString(String s) { char[] cs = s.toCharArray(); int n = cs.length; boolean[][][] f = new boolean[n+1][n+1][n+1]; f[0][0][0] = true; for (int i = 0; i < n; i++) { for (int j = 0; j <= i; j++) { for (int k = 0; k <= j; k++) { if (cs[i] == '(') { f[i+1][j+1][k] |= f[i][j][k]; } else if (cs[i] == ')') { f[i+1][j][k+1] |= f[i][j][k]; } else if (cs[i] == '*') { f[i+1][j+1][k] |= f[i][j][k]; f[i+1][j][k+1] |= f[i][j][k]; f[i+1][j][k] |= f[i][j][k]; } } } } for (int i = 0; i <= n; i++) { if (f[n][i][i]) return true; } return false; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Solution { public boolean checkValidString(String s) { char[] cs = s.toCharArray(); int n = cs.length; boolean[][] f = new boolean[n+1][n+1]; f[0][0] = true; for (int i = 0; i < n; i++) { for (int j = 0; j <= i; j++) { if (cs[i] == '(') { f[i+1][j+1] |= f[i][j]; } else if (cs[i] == ')') { if (j-1 >= 0) f[i+1][j-1] |= f[i][j]; } else if (cs[i] == '*') { f[i+1][j+1] |= f[i][j]; if (j-1 >= 0) f[i+1][j-1] |= f[i][j]; f[i+1][j] |= f[i][j]; } } } return f[n][0]; } }
|