20. 有效的括号(简单)

1,问题描述

20. 有效的括号

难度:简单

给定一个只包括 '('')''{''}''['']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。

示例 1:

**输入:**s = “()”

**输出:**true

示例 2:

**输入:**s = “()[]{}”

**输出:**true

示例 3:

**输入:**s = “(]”

**输出:**false

示例 4:

**输入:**s = “([])”

**输出:**true

提示:

  • 1 <= s.length <= 104
  • s 仅由括号 '()[]{}' 组成

2,初步思考

​ 模式识别:分治合并是我首先想到的解法,str是否合规取决于str里面的是否合规,所以直接递归求解解决

​ 官方使用的方法更巧妙,使用的stack栈的解法,入栈准备作为新来数据的匹配项,如果匹配就出栈,继续循环

3,代码处理

第一次的思路想复杂了

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import java.util.*;

public class _20有效的括号 {


// 直接使用stack栈进行解决
public boolean isValid_stack(String s) {
if (s == null || s.isEmpty()) {
return true;
}
if (s.length() % 2 != 0) {
return false;
}

Stack<Character> stack = new Stack<>();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (!stack.isEmpty() && getBeforeChar(c) == stack.peek()) {
stack.pop();
} else {
stack.add(c);
}
}
return stack.isEmpty();
}

// 可以采用递归求解
static Map<String, Boolean> map = new HashMap<>();

public boolean isValid(String s) {
boolean flag = false;
if (map.containsKey(s)) {
return map.get(s);
} else if (s.isEmpty()) {
map.put(s, true);
return true;
} else if (s.length() % 2 != 0 || !setLeft.contains(s.charAt(0)) || !setRight.contains(s.charAt(s.length() - 1))) {
// 奇数、或者开头结尾不匹配、或者开头结尾不匹配
map.put(s, false);
return false;
} else if (getNextChar(s.charAt(0)) == s.charAt(s.length() - 1)) {
flag = isValid(s.substring(1, s.length() - 1));
if (flag) {
map.put(s, true);
return true;
}
}

for (int i = 1; i < s.length() - 1; i = i + 2) {
flag = isValid(s.substring(0, i + 1)) && isValid(s.substring(i + 1, s.length()));
if (flag) {
map.put(s, true);
return true;
}
}
map.put(s, false);
return false;
}

private char getNextChar(char preChar) {
switch (preChar) {
case '(':
return ')';
case '[':
return ']';
case '{':
return '}';
default:
return ' ';
}
}

private char getBeforeChar(char preChar) {
switch (preChar) {
case ')':
return '(';
case ']':
return '[';
case '}':
return '{';
default:
return ' ';
}
}

private static Set<Character> setLeft = null;
private static Set<Character> setRight = null;

static {
setLeft = new HashSet<>();
setLeft.add('(');
setLeft.add('[');
setLeft.add('{');
setRight = new HashSet<>();
setRight.add(')');
setRight.add(']');
setRight.add('}');
}


public static void main(String[] args) {
_20有效的括号 valid = new _20有效的括号();
// System.out.println(valid.isValid("[[[]]]{}"));
// System.out.println(valid.isValid("()[]{}"));
// System.out.println(valid.isValid("([])"));
System.out.println(valid.isValid_stack("{}{{}}"));
}
}

// [[[]]]

​ 官方题解中速度最快的解法,本质与stack栈一致

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
class Solution {
public boolean isValid(String s) {
char[] s1 = s.toCharArray();
int[] ss = new int[s.length()];
int top = -1,n = s.length();
for(int i = 0;i < n;i ++){
if(s1[i] == '(' || s1[i] == '{' || s1[i] == '['){
ss[++ top] = s1[i];
}
else{
if(s1[i] == ')'){
if(top == -1 || ss[top] != '(')
return false;
top --;
}
else if(s1[i] == '}'){
if(top == -1 || ss[top] != '{')
return false;
top --;
}
else if(s1[i] == ']'){
if(top == -1 || ss[top] != '[')
return false;
top --;
}
}
}
return top == -1;
}
}

4,扩展知识

栈stack是你可以把它理解为一个一端封闭的隧道,且宽度只允许一个人

所以会出现,先进后出的情况

5,参考链接

Java Stack 类