Skip to content

Commit 61afad6

Browse files
committed
feat: add solutions to lc problem: No.0921
No.0921.Minimum Add to Make Parentheses Valid
1 parent 1c22d53 commit 61afad6

File tree

6 files changed

+226
-95
lines changed

6 files changed

+226
-95
lines changed

solution/0900-0999/0921.Minimum Add to Make Parentheses Valid/README.md

Lines changed: 112 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,34 @@
5151

5252
<!-- 这里可写通用的实现逻辑 -->
5353

54+
**方法一:贪心 + 栈**
55+
56+
这个问题属于经典的括号匹配问题,可以使用“贪心 + 栈”来解决。
57+
58+
遍历字符串 $s$ 的每个字符 $c$:
59+
60+
- 若 $c$ 为左括号,直接将 $c$ 入栈;
61+
- 若 $c$ 为右括号,此时如果栈不为空,且栈顶元素为左括号,则将栈顶元素出栈,表示匹配成功;否则将 $c$ 入栈。
62+
63+
遍历结束后,栈中剩余的元素个数即为需要添加的括号数。
64+
65+
时间复杂度为 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为字符串 $s$ 的长度。
66+
67+
**方法二:贪心 + 计数**
68+
69+
方法一借助了栈来实现括号匹配,也可以直接通过计数来实现。
70+
71+
定义变量 `cnt` 表示当前待匹配的左括号个数,变量 `ans` 记录答案。初始时两个变量的值均为 $0$。
72+
73+
同样遍历字符串 $s$ 的每个字符 $c$:
74+
75+
- 若 $c$ 为左括号,将 `cnt` 的值增加 $1$;
76+
- 若 $c$ 为右括号,此时如果 $cnt \gt 0$,说明当前有左括号可以匹配,将 `cnt` 的值减 $1$;否则说明当前右括号无法匹配,将 `ans` 的值增加 $1$。
77+
78+
遍历结束后,将 `cnt` 的值加到 `ans` 中,即为答案。
79+
80+
时间复杂度为 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为字符串 $s$ 的长度。
81+
5482
<!-- tabs:start -->
5583

5684
### **Python3**
@@ -62,16 +90,28 @@ class Solution:
6290
def minAddToMakeValid(self, s: str) -> int:
6391
stk = []
6492
for c in s:
65-
if c == '(':
66-
stk.append(c)
93+
if c == ')' and stk and stk[-1] == '(':
94+
stk.pop()
6795
else:
68-
if stk and stk[-1] == '(':
69-
stk.pop()
70-
else:
71-
stk.append(c)
96+
stk.append(c)
7297
return len(stk)
7398
```
7499

100+
```python
101+
class Solution:
102+
def minAddToMakeValid(self, s: str) -> int:
103+
ans = cnt = 0
104+
for c in s:
105+
if c == '(':
106+
cnt += 1
107+
elif cnt:
108+
cnt -= 1
109+
else:
110+
ans += 1
111+
ans += cnt
112+
return ans
113+
```
114+
75115
### **Java**
76116

77117
<!-- 这里可写当前语言的特殊实现逻辑 -->
@@ -81,63 +121,104 @@ class Solution {
81121
public int minAddToMakeValid(String s) {
82122
Deque<Character> stk = new ArrayDeque<>();
83123
for (char c : s.toCharArray()) {
84-
if (c == '(') {
85-
stk.push(c);
124+
if (c == ')' && !stk.isEmpty() && stk.peek() == '(') {
125+
stk.pop();
86126
} else {
87-
if (!stk.isEmpty() && stk.peek() == '(') {
88-
stk.pop();
89-
} else {
90-
stk.push(c);
91-
}
127+
stk.push(c);
92128
}
93129
}
94130
return stk.size();
95131
}
96132
}
97133
```
98134

135+
```java
136+
class Solution {
137+
public int minAddToMakeValid(String s) {
138+
int ans = 0, cnt = 0;
139+
for (char c : s.toCharArray()) {
140+
if (c == '(') {
141+
++cnt;
142+
} else if (cnt > 0) {
143+
--cnt;
144+
} else {
145+
++ans;
146+
}
147+
}
148+
ans += cnt;
149+
return ans;
150+
}
151+
}
152+
```
153+
99154
### **C++**
100155

101156
```cpp
102157
class Solution {
103158
public:
104159
int minAddToMakeValid(string s) {
105-
stack<char> stk;
106-
for (char& c : s) {
107-
if (c == '(')
108-
stk.push(c);
109-
else {
110-
if (!stk.empty() && stk.top() == '(') {
111-
stk.pop();
112-
} else
113-
stk.push(c);
114-
}
160+
string stk;
161+
for (char c : s) {
162+
if (c == ')' && stk.size() && stk.back() == '(') stk.pop_back();
163+
else stk.push_back(c);
115164
}
116165
return stk.size();
117166
}
118167
};
119168
```
120169
170+
```cpp
171+
class Solution {
172+
public:
173+
int minAddToMakeValid(string s) {
174+
int ans = 0, cnt = 0;
175+
for (char c : s) {
176+
if (c == '(')
177+
++cnt;
178+
else if (cnt)
179+
--cnt;
180+
else
181+
++ans;
182+
}
183+
ans += cnt;
184+
return ans;
185+
}
186+
};
187+
```
188+
121189
### **Go**
122190

123191
```go
124192
func minAddToMakeValid(s string) int {
125-
var stk []rune
193+
stk := []rune{}
126194
for _, c := range s {
127-
if c == '(' {
128-
stk = append(stk, c)
195+
if c == ')' && len(stk) > 0 && stk[len(stk)-1] == '(' {
196+
stk = stk[:len(stk)-1]
129197
} else {
130-
if len(stk) > 0 && stk[len(stk)-1] == '(' {
131-
stk = stk[:len(stk)-1]
132-
} else {
133-
stk = append(stk, c)
134-
}
198+
stk = append(stk, c)
135199
}
136200
}
137201
return len(stk)
138202
}
139203
```
140204

205+
```go
206+
func minAddToMakeValid(s string) int {
207+
ans, cnt := 0, 0
208+
for _, c := range s {
209+
if c == '(' {
210+
cnt++
211+
} else if cnt > 0 {
212+
cnt--
213+
} else {
214+
ans++
215+
}
216+
}
217+
ans += cnt
218+
return ans
219+
}
220+
```
221+
141222
### **...**
142223

143224
```

solution/0900-0999/0921.Minimum Add to Make Parentheses Valid/README_EN.md

Lines changed: 84 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -54,80 +54,133 @@ class Solution:
5454
def minAddToMakeValid(self, s: str) -> int:
5555
stk = []
5656
for c in s:
57-
if c == '(':
58-
stk.append(c)
57+
if c == ')' and stk and stk[-1] == '(':
58+
stk.pop()
5959
else:
60-
if stk and stk[-1] == '(':
61-
stk.pop()
62-
else:
63-
stk.append(c)
60+
stk.append(c)
6461
return len(stk)
6562
```
6663

64+
```python
65+
class Solution:
66+
def minAddToMakeValid(self, s: str) -> int:
67+
ans = cnt = 0
68+
for c in s:
69+
if c == '(':
70+
cnt += 1
71+
elif cnt:
72+
cnt -= 1
73+
else:
74+
ans += 1
75+
ans += cnt
76+
return ans
77+
```
78+
6779
### **Java**
6880

6981
```java
7082
class Solution {
7183
public int minAddToMakeValid(String s) {
7284
Deque<Character> stk = new ArrayDeque<>();
7385
for (char c : s.toCharArray()) {
74-
if (c == '(') {
75-
stk.push(c);
86+
if (c == ')' && !stk.isEmpty() && stk.peek() == '(') {
87+
stk.pop();
7688
} else {
77-
if (!stk.isEmpty() && stk.peek() == '(') {
78-
stk.pop();
79-
} else {
80-
stk.push(c);
81-
}
89+
stk.push(c);
8290
}
8391
}
8492
return stk.size();
8593
}
8694
}
8795
```
8896

97+
```java
98+
class Solution {
99+
public int minAddToMakeValid(String s) {
100+
int ans = 0, cnt = 0;
101+
for (char c : s.toCharArray()) {
102+
if (c == '(') {
103+
++cnt;
104+
} else if (cnt > 0) {
105+
--cnt;
106+
} else {
107+
++ans;
108+
}
109+
}
110+
ans += cnt;
111+
return ans;
112+
}
113+
}
114+
```
115+
89116
### **C++**
90117

91118
```cpp
92119
class Solution {
93120
public:
94121
int minAddToMakeValid(string s) {
95-
stack<char> stk;
96-
for (char& c : s) {
97-
if (c == '(')
98-
stk.push(c);
99-
else {
100-
if (!stk.empty() && stk.top() == '(') {
101-
stk.pop();
102-
} else
103-
stk.push(c);
104-
}
122+
string stk;
123+
for (char c : s) {
124+
if (c == ')' && stk.size() && stk.back() == '(') stk.pop_back();
125+
else stk.push_back(c);
105126
}
106127
return stk.size();
107128
}
108129
};
109130
```
110131
132+
```cpp
133+
class Solution {
134+
public:
135+
int minAddToMakeValid(string s) {
136+
int ans = 0, cnt = 0;
137+
for (char c : s) {
138+
if (c == '(')
139+
++cnt;
140+
else if (cnt)
141+
--cnt;
142+
else
143+
++ans;
144+
}
145+
ans += cnt;
146+
return ans;
147+
}
148+
};
149+
```
150+
111151
### **Go**
112152

113153
```go
114154
func minAddToMakeValid(s string) int {
115-
var stk []rune
155+
stk := []rune{}
116156
for _, c := range s {
117-
if c == '(' {
118-
stk = append(stk, c)
157+
if c == ')' && len(stk) > 0 && stk[len(stk)-1] == '(' {
158+
stk = stk[:len(stk)-1]
119159
} else {
120-
if len(stk) > 0 && stk[len(stk)-1] == '(' {
121-
stk = stk[:len(stk)-1]
122-
} else {
123-
stk = append(stk, c)
124-
}
160+
stk = append(stk, c)
125161
}
126162
}
127163
return len(stk)
128164
}
129165
```
130166

167+
```go
168+
func minAddToMakeValid(s string) int {
169+
ans, cnt := 0, 0
170+
for _, c := range s {
171+
if c == '(' {
172+
cnt++
173+
} else if cnt > 0 {
174+
cnt--
175+
} else {
176+
ans++
177+
}
178+
}
179+
ans += cnt
180+
return ans
181+
}
182+
```
183+
131184
### **...**
132185

133186
```
Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
class Solution {
22
public:
33
int minAddToMakeValid(string s) {
4-
stack<char> stk;
5-
for (char& c : s) {
4+
int ans = 0, cnt = 0;
5+
for (char c : s) {
66
if (c == '(')
7-
stk.push(c);
8-
else {
9-
if (!stk.empty() && stk.top() == '(') {
10-
stk.pop();
11-
} else
12-
stk.push(c);
13-
}
7+
++cnt;
8+
else if (cnt)
9+
--cnt;
10+
else
11+
++ans;
1412
}
15-
return stk.size();
13+
ans += cnt;
14+
return ans;
1615
}
1716
};

0 commit comments

Comments
 (0)