# 20. 有效的括号 - 力扣题解最佳实践
访问原文链接:[20. 有效的括号 - 力扣题解最佳实践](https://leetcoder.net/zh/leetcode/20-valid-parentheses),体验更佳!
力扣链接:[20. 有效的括号](https://leetcode.cn/problems/valid-parentheses), 难度:**简单**。
## 力扣“20. 有效的括号”问题描述
给定一个只包括 `(`,`)`,`{`,`}`,`[`,`]` 的字符串 `s` ,判断字符串是否有效。
有效字符串需满足:
1. 左括号必须用相同类型的右括号闭合。
2. 左括号必须以正确的顺序闭合。
3. 每个右括号都有一个对应的相同类型的左括号。
### [示例 1]
**输入**: `s = "()"`
**输出**: `true`
### [示例 2]
**输入**: `s = "()[]{}"`
**输出**: `true`
### [示例 3]
**输入**: `s = "(]"`
**输出**: `false`
### [示例 4]
**输入**: `s = "([])"`
**输出**: `true`
### [约束]
- `1 <= s.length <= 10000`
- `s` 仅由括号 `()[]{}` 组成
### [Hints]
提示 1
Use a stack of characters.
提示 2
When you encounter an opening bracket, push it to the top of the stack.
提示 3
When you encounter a closing bracket, check if the top of the stack was the opening for it. If yes, pop it from the stack. Otherwise, return false.
## 思路
1. 括号匹配关注的主要是`前一个字符`与`当前字符`。有两种情况要考虑:
1. 如果`当前字符`是左括号,则不需要匹配,直接保存起来。
2. 如果`当前字符`是右括号,并且`前一个字符`与`当前字符`配成了一对,则这两个字符都可以**消失**了;反之,如果配对失败,直接返回`false`。
2. 这种关注`前一个字符`与`当前字符`的场景,适合用`栈`实现。
3. 左右括号之间的对应关系可以保存在一个`Map`中。
4. 最后,如果栈为空,说明全部配对成功,返回`true`;否则返回`false`。
## 复杂度
- 时间复杂度: `O(N)`.
- 空间复杂度: `O(N)`.
## JavaScript
```javascript
/**
* @param {string} s
* @return {boolean}
*/
var isValid = function (s) {
const closeToOpen = new Map([
[')', '('],
['}', '{'],
[']', '['],
])
const stack = []
for (const char of s) {
if (!closeToOpen.has(char)) {
// is open bracket
stack.push(char)
continue
}
// is close bracket
if (stack.length === 0) {
return false
}
// stack top value doesn't match the expected value
if (stack.pop() != closeToOpen.get(char)) {
return false
}
}
return stack.length === 0
};
```
## Python
```python
class Solution:
def isValid(self, s: str) -> bool:
# Map closing brackets to their opening brackets
close_to_open = {
')': '(',
'}': '{',
']': '[',
}
stack = []
for char in s:
if char not in close_to_open:
# is open bracket
stack.append(char)
continue
# is close bracket
if not stack:
return False
# stack top value doesn't match the expected value
if stack.pop() != close_to_open[char]:
return False
return not stack
```
## Java
```java
class Solution {
public boolean isValid(String s) {
// Map closing brackets to their opening brackets
var closeToOpen = new HashMap();
closeToOpen.put(')', '(');
closeToOpen.put('}', '{');
closeToOpen.put(']', '[');
var stack = new Stack();
for (char c : s.toCharArray()) {
if (!closeToOpen.containsKey(c)) {
// is open bracket
stack.push(c);
continue;
}
// is close bracket
if (stack.isEmpty()) {
return false;
}
// stack top value doesn't match the expected value
if (stack.pop() != closeToOpen.get(c)) {
return false;
}
}
return stack.isEmpty();
}
}
```
## C++
```cpp
class Solution {
public:
bool isValid(string s) {
// Map closing brackets to their opening brackets
unordered_map closeToOpen = {
{')', '('},
{'}', '{'},
{']', '['}
};
stack st;
for (char c : s) {
if (closeToOpen.find(c) == closeToOpen.end()) {
// is open bracket
st.push(c);
continue;
}
// is close bracket
if (st.empty()) {
return false;
}
// stack top value doesn't match the expected value
if (st.top() != closeToOpen[c]) {
return false;
}
st.pop();
}
return st.empty();
}
};
```
## C#
```csharp
public class Solution
{
public bool IsValid(string s)
{
// Map closing brackets to their opening brackets
var closeToOpen = new Dictionary()
{
{')', '('},
{'}', '{'},
{']', '['}
};
var stack = new Stack();
foreach (char c in s) {
if (!closeToOpen.ContainsKey(c))
{
// is open bracket
stack.Push(c);
continue;
}
// is close bracket
if (stack.Count == 0)
{
return false;
}
// stack top value doesn't match the expected value
if (stack.Pop() != closeToOpen[c])
{
return false;
}
}
return stack.Count == 0;
}
}
```
## Go
```go
func isValid(s string) bool {
// Map closing brackets to their opening brackets
closeToOpen := map[rune]rune{
')': '(',
'}': '{',
']': '[',
}
stack := []rune{}
for _, char := range s {
if _, isClose := closeToOpen[char]; !isClose {
// is open bracket
stack = append(stack, char)
continue
}
// is close bracket
if len(stack) == 0 {
return false
}
lastChar := stack[len(stack) - 1]
// stack top value doesn't match the expected value
if lastChar != closeToOpen[char] {
return false
}
stack = stack[:len(stack) - 1] // pop operation
}
return len(stack) == 0
}
```
## Ruby
```ruby
# @param {String} s
# @return {Boolean}
def is_valid(s)
# Map closing brackets to their opening brackets
close_to_open = {
')' => '(',
'}' => '{',
']' => '['
}
stack = []
s.each_char do |char|
if !close_to_open.key?(char)
# is open bracket
stack.push(char)
next
end
# is close bracket
if stack.empty?
return false
end
# stack top value doesn't match the expected value
if stack.pop != close_to_open[char]
return false
end
end
stack.empty?
end
```
## Other languages
```java
// Welcome to create a PR to complete the code of this language, thanks!
```
亲爱的力扣人,为了您更好的刷题体验,请访问 [leetcoder.net](https://leetcoder.net/zh)。
本站敢称力扣题解最佳实践,终将省你大量刷题时间!
原文链接:[20. 有效的括号 - 力扣题解最佳实践](https://leetcoder.net/zh/leetcode/20-valid-parentheses).
GitHub 仓库: [f*ck-leetcode](https://github.com/fuck-leetcode/fuck-leetcode).