Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 119 additions & 5 deletions solution/3700-3799/3703.Remove K-Balanced Substrings/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,32 +162,146 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3700-3799/3703.Re

<!-- solution:start -->

### 方法一
### 方法一:栈

我们用一个栈来维护当前字符串的状态。栈中的每个元素是一个二元组,表示某个字符及其连续出现的次数。

遍历字符串中的每个字符:

- 如果栈不为空且栈顶元素的字符与当前字符相同,则将栈顶元素的计数加一。
- 否则,将当前字符和计数 1 作为一个新元素压入栈中。
- 如果当前字符是 `')'`,且栈中至少有两个元素,且栈顶元素的计数等于 $k$,且栈顶元素的前一个元素的计数大于等于 $k$,则弹出栈顶元素,并将前一个元素的计数减去 $k$。如果前一个元素的计数变为 0,则也将其弹出。

遍历结束后,栈中剩下的元素即为最终字符串的状态。我们将这些元素按顺序连接起来,得到结果字符串。

时间复杂度 $O(n)$,空间复杂度 $O(n)$,其中 $n$ 是字符串 $s$ 的长度。

<!-- tabs:start -->

#### Python3

```python

class Solution:
def removeSubstring(self, s: str, k: int) -> str:
stk = []
for c in s:
if stk and stk[-1][0] == c:
stk[-1][1] += 1
else:
stk.append([c, 1])
if c == ")" and len(stk) > 1 and stk[-1][1] == k and stk[-2][1] >= k:
stk.pop()
stk[-1][1] -= k
if stk[-1][1] == 0:
stk.pop()
return "".join(c * v for c, v in stk)
```

#### Java

```java

class Solution {
public String removeSubstring(String s, int k) {
List<int[]> stk = new ArrayList<>();
for (char c : s.toCharArray()) {
if (!stk.isEmpty() && stk.get(stk.size() - 1)[0] == c) {
stk.get(stk.size() - 1)[1] += 1;
} else {
stk.add(new int[]{c, 1});
}
if (c == ')' && stk.size() > 1) {
int[] top = stk.get(stk.size() - 1);
int[] prev = stk.get(stk.size() - 2);
if (top[1] == k && prev[1] >= k) {
stk.remove(stk.size() - 1);
prev[1] -= k;
if (prev[1] == 0) {
stk.remove(stk.size() - 1);
}
}
}
}
StringBuilder sb = new StringBuilder();
for (int[] pair : stk) {
for (int i = 0; i < pair[1]; i++) {
sb.append((char) pair[0]);
}
}
return sb.toString();
}
}
```

#### C++

```cpp

class Solution {
public:
string removeSubstring(string s, int k) {
vector<pair<char, int>> stk;
for (char c : s) {
if (!stk.empty() && stk.back().first == c) {
stk.back().second += 1;
} else {
stk.emplace_back(c, 1);
}
if (c == ')' && stk.size() > 1) {
auto& top = stk.back();
auto& prev = stk[stk.size() - 2];
if (top.second == k && prev.second >= k) {
stk.pop_back();
prev.second -= k;
if (prev.second == 0) {
stk.pop_back();
}
}
}
}
string res;
for (auto& p : stk) {
res.append(p.second, p.first);
}
return res;
}
};
```

#### Go

```go

func removeSubstring(s string, k int) string {
type pair struct {
ch byte
count int
}
stk := make([]pair, 0)
for i := 0; i < len(s); i++ {
c := s[i]
if len(stk) > 0 && stk[len(stk)-1].ch == c {
stk[len(stk)-1].count++
} else {
stk = append(stk, pair{c, 1})
}
if c == ')' && len(stk) > 1 {
top := &stk[len(stk)-1]
prev := &stk[len(stk)-2]
if top.count == k && prev.count >= k {
stk = stk[:len(stk)-1]
prev.count -= k
if prev.count == 0 {
stk = stk[:len(stk)-1]
}
}
}
}
res := make([]byte, 0)
for _, p := range stk {
for i := 0; i < p.count; i++ {
res = append(res, p.ch)
}
}
return string(res)
}
```

<!-- tabs:end -->
Expand Down
124 changes: 119 additions & 5 deletions solution/3700-3799/3703.Remove K-Balanced Substrings/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,32 +157,146 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3700-3799/3703.Re

<!-- solution:start -->

### Solution 1
### Solution 1: Stack

We use a stack to maintain the current state of the string. Each element in the stack is a pair representing a character and its consecutive count.

Traverse each character in the string:

- If the stack is not empty and the character of the top element matches the current character, increment the count of the top element.
- Otherwise, push the current character with count 1 as a new element onto the stack.
- If the current character is `')'`, and there are at least two elements in the stack, and the count of the top element equals $k$, and the count of the previous element is greater than or equal to $k$, then pop the top element and subtract $k$ from the count of the previous element. If the count of the previous element becomes 0, pop it as well.

After traversal, the remaining elements in the stack represent the final state of the string. We concatenate these elements in order to get the result string.

The time complexity is $O(n)$ and the space complexity is $O(n)$, where $n$ is the length of string $s$.

<!-- tabs:start -->

#### Python3

```python

class Solution:
def removeSubstring(self, s: str, k: int) -> str:
stk = []
for c in s:
if stk and stk[-1][0] == c:
stk[-1][1] += 1
else:
stk.append([c, 1])
if c == ")" and len(stk) > 1 and stk[-1][1] == k and stk[-2][1] >= k:
stk.pop()
stk[-1][1] -= k
if stk[-1][1] == 0:
stk.pop()
return "".join(c * v for c, v in stk)
```

#### Java

```java

class Solution {
public String removeSubstring(String s, int k) {
List<int[]> stk = new ArrayList<>();
for (char c : s.toCharArray()) {
if (!stk.isEmpty() && stk.get(stk.size() - 1)[0] == c) {
stk.get(stk.size() - 1)[1] += 1;
} else {
stk.add(new int[]{c, 1});
}
if (c == ')' && stk.size() > 1) {
int[] top = stk.get(stk.size() - 1);
int[] prev = stk.get(stk.size() - 2);
if (top[1] == k && prev[1] >= k) {
stk.remove(stk.size() - 1);
prev[1] -= k;
if (prev[1] == 0) {
stk.remove(stk.size() - 1);
}
}
}
}
StringBuilder sb = new StringBuilder();
for (int[] pair : stk) {
for (int i = 0; i < pair[1]; i++) {
sb.append((char) pair[0]);
}
}
return sb.toString();
}
}
```

#### C++

```cpp

class Solution {
public:
string removeSubstring(string s, int k) {
vector<pair<char, int>> stk;
for (char c : s) {
if (!stk.empty() && stk.back().first == c) {
stk.back().second += 1;
} else {
stk.emplace_back(c, 1);
}
if (c == ')' && stk.size() > 1) {
auto& top = stk.back();
auto& prev = stk[stk.size() - 2];
if (top.second == k && prev.second >= k) {
stk.pop_back();
prev.second -= k;
if (prev.second == 0) {
stk.pop_back();
}
}
}
}
string res;
for (auto& p : stk) {
res.append(p.second, p.first);
}
return res;
}
};
```

#### Go

```go

func removeSubstring(s string, k int) string {
type pair struct {
ch byte
count int
}
stk := make([]pair, 0)
for i := 0; i < len(s); i++ {
c := s[i]
if len(stk) > 0 && stk[len(stk)-1].ch == c {
stk[len(stk)-1].count++
} else {
stk = append(stk, pair{c, 1})
}
if c == ')' && len(stk) > 1 {
top := &stk[len(stk)-1]
prev := &stk[len(stk)-2]
if top.count == k && prev.count >= k {
stk = stk[:len(stk)-1]
prev.count -= k
if prev.count == 0 {
stk = stk[:len(stk)-1]
}
}
}
}
res := make([]byte, 0)
for _, p := range stk {
for i := 0; i < p.count; i++ {
res = append(res, p.ch)
}
}
return string(res)
}
```

<!-- tabs:end -->
Expand Down
29 changes: 29 additions & 0 deletions solution/3700-3799/3703.Remove K-Balanced Substrings/Solution.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
class Solution {
public:
string removeSubstring(string s, int k) {
vector<pair<char, int>> stk;
for (char c : s) {
if (!stk.empty() && stk.back().first == c) {
stk.back().second += 1;
} else {
stk.emplace_back(c, 1);
}
if (c == ')' && stk.size() > 1) {
auto& top = stk.back();
auto& prev = stk[stk.size() - 2];
if (top.second == k && prev.second >= k) {
stk.pop_back();
prev.second -= k;
if (prev.second == 0) {
stk.pop_back();
}
}
}
}
string res;
for (auto& p : stk) {
res.append(p.second, p.first);
}
return res;
}
};
33 changes: 33 additions & 0 deletions solution/3700-3799/3703.Remove K-Balanced Substrings/Solution.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
func removeSubstring(s string, k int) string {
type pair struct {
ch byte
count int
}
stk := make([]pair, 0)
for i := 0; i < len(s); i++ {
c := s[i]
if len(stk) > 0 && stk[len(stk)-1].ch == c {
stk[len(stk)-1].count++
} else {
stk = append(stk, pair{c, 1})
}
if c == ')' && len(stk) > 1 {
top := &stk[len(stk)-1]
prev := &stk[len(stk)-2]
if top.count == k && prev.count >= k {
stk = stk[:len(stk)-1]
prev.count -= k
if prev.count == 0 {
stk = stk[:len(stk)-1]
}
}
}
}
res := make([]byte, 0)
for _, p := range stk {
for i := 0; i < p.count; i++ {
res = append(res, p.ch)
}
}
return string(res)
}
30 changes: 30 additions & 0 deletions solution/3700-3799/3703.Remove K-Balanced Substrings/Solution.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
class Solution {
public String removeSubstring(String s, int k) {
List<int[]> stk = new ArrayList<>();
for (char c : s.toCharArray()) {
if (!stk.isEmpty() && stk.get(stk.size() - 1)[0] == c) {
stk.get(stk.size() - 1)[1] += 1;
} else {
stk.add(new int[]{c, 1});
}
if (c == ')' && stk.size() > 1) {
int[] top = stk.get(stk.size() - 1);
int[] prev = stk.get(stk.size() - 2);
if (top[1] == k && prev[1] >= k) {
stk.remove(stk.size() - 1);
prev[1] -= k;
if (prev[1] == 0) {
stk.remove(stk.size() - 1);
}
}
}
}
StringBuilder sb = new StringBuilder();
for (int[] pair : stk) {
for (int i = 0; i < pair[1]; i++) {
sb.append((char) pair[0]);
}
}
return sb.toString();
}
}
Loading
Loading