Skip to content

Commit bd50c80

Browse files
authored
feat: add solutions to lc problem: No.424 (#3029)
No.0424.Longest Repeating Character Replacement
1 parent 0b82ca4 commit bd50c80

File tree

7 files changed

+169
-131
lines changed

7 files changed

+169
-131
lines changed

solution/0400-0499/0424.Longest Repeating Character Replacement/README.md

+61-44
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,15 @@ tags:
5959

6060
<!-- solution:start -->
6161

62-
### 方法一
62+
### 方法一:双指针
63+
64+
我们使用一个哈希表 `cnt` 统计字符串中每个字符出现的次数,使用双指针 `l``r` 维护一个滑动窗口,使得窗口的大小减去出现次数最多的字符的次数,结果不超过 $k$。
65+
66+
我们遍历字符串,每次更新窗口的右边界 `r`,并更新窗口内的字符出现次数,同时更新出现过的字符的最大出现次数 `mx`。当窗口的大小减去 `mx` 大于 $k$ 时,我们需要缩小窗口的左边界 `l`,同时更新窗口内的字符出现次数,直到窗口的大小减去 `mx` 不大于 $k$。
67+
68+
最后,答案为 $n - l$,其中 $n$ 为字符串的长度。
69+
70+
时间复杂度 $O(n)$,空间复杂度 $O(|\Sigma|)$。其中 $n$ 为字符串的长度,而 $|\Sigma|$ 为字符集的大小,本题中字符集为大写英文字母,所以 $|\Sigma| = 26$。
6371

6472
<!-- tabs:start -->
6573

@@ -68,36 +76,32 @@ tags:
6876
```python
6977
class Solution:
7078
def characterReplacement(self, s: str, k: int) -> int:
71-
counter = [0] * 26
72-
i = j = maxCnt = 0
73-
while i < len(s):
74-
counter[ord(s[i]) - ord('A')] += 1
75-
maxCnt = max(maxCnt, counter[ord(s[i]) - ord('A')])
76-
if i - j + 1 > maxCnt + k:
77-
counter[ord(s[j]) - ord('A')] -= 1
78-
j += 1
79-
i += 1
80-
return i - j
79+
cnt = Counter()
80+
l = mx = 0
81+
for r, c in enumerate(s):
82+
cnt[c] += 1
83+
mx = max(mx, cnt[c])
84+
if r - l + 1 - mx > k:
85+
cnt[s[l]] -= 1
86+
l += 1
87+
return len(s) - l
8188
```
8289

8390
#### Java
8491

8592
```java
8693
class Solution {
8794
public int characterReplacement(String s, int k) {
88-
int[] counter = new int[26];
89-
int i = 0;
90-
int j = 0;
91-
for (int maxCnt = 0; i < s.length(); ++i) {
92-
char c = s.charAt(i);
93-
++counter[c - 'A'];
94-
maxCnt = Math.max(maxCnt, counter[c - 'A']);
95-
if (i - j + 1 - maxCnt > k) {
96-
--counter[s.charAt(j) - 'A'];
97-
++j;
95+
int[] cnt = new int[26];
96+
int l = 0, mx = 0;
97+
int n = s.length();
98+
for (int r = 0; r < n; ++r) {
99+
mx = Math.max(mx, ++cnt[s.charAt(r) - 'A']);
100+
if (r - l + 1 - mx > k) {
101+
--cnt[s.charAt(l++) - 'A'];
98102
}
99103
}
100-
return i - j;
104+
return n - l;
101105
}
102106
}
103107
```
@@ -108,18 +112,16 @@ class Solution {
108112
class Solution {
109113
public:
110114
int characterReplacement(string s, int k) {
111-
vector<int> counter(26);
112-
int i = 0, j = 0, maxCnt = 0;
113-
for (char& c : s) {
114-
++counter[c - 'A'];
115-
maxCnt = max(maxCnt, counter[c - 'A']);
116-
if (i - j + 1 > maxCnt + k) {
117-
--counter[s[j] - 'A'];
118-
++j;
115+
int cnt[26]{};
116+
int l = 0, mx = 0;
117+
int n = s.length();
118+
for (int r = 0; r < n; ++r) {
119+
mx = max(mx, ++cnt[s[r] - 'A']);
120+
if (r - l + 1 - mx > k) {
121+
--cnt[s[l++] - 'A'];
119122
}
120-
++i;
121123
}
122-
return i - j;
124+
return n - l;
123125
}
124126
};
125127
```
@@ -128,20 +130,35 @@ public:
128130
129131
```go
130132
func characterReplacement(s string, k int) int {
131-
counter := make([]int, 26)
132-
j, maxCnt := 0, 0
133-
for i := range s {
134-
c := s[i] - 'A'
135-
counter[c]++
136-
if maxCnt < counter[c] {
137-
maxCnt = counter[c]
138-
}
139-
if i-j+1 > maxCnt+k {
140-
counter[s[j]-'A']--
141-
j++
133+
cnt := [26]int{}
134+
l, mx := 0, 0
135+
for r, c := range s {
136+
cnt[c-'A']++
137+
mx = max(mx, cnt[c-'A'])
138+
if r-l+1-mx > k {
139+
cnt[s[l]-'A']--
140+
l++
142141
}
143142
}
144-
return len(s) - j
143+
return len(s) - l
144+
}
145+
```
146+
147+
#### TypeScript
148+
149+
```ts
150+
function characterReplacement(s: string, k: number): number {
151+
const idx = (c: string) => c.charCodeAt(0) - 65;
152+
const cnt: number[] = Array(26).fill(0);
153+
const n = s.length;
154+
let [l, mx] = [0, 0];
155+
for (let r = 0; r < n; ++r) {
156+
mx = Math.max(mx, ++cnt[idx(s[r])]);
157+
if (r - l + 1 - mx > k) {
158+
--cnt[idx(s[l++])];
159+
}
160+
}
161+
return n - l;
145162
}
146163
```
147164

solution/0400-0499/0424.Longest Repeating Character Replacement/README_EN.md

+61-44
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,15 @@ There may exists other ways to achieve this answer too.</pre>
5555

5656
<!-- solution:start -->
5757

58-
### Solution 1
58+
### Solution 1: Two Pointers
59+
60+
We use a hash table `cnt` to count the occurrence of each character in the string, and two pointers `l` and `r` to maintain a sliding window, such that the size of the window minus the count of the most frequent character does not exceed $k$.
61+
62+
We iterate through the string, updating the right boundary `r` of the window each time, updating the count of characters within the window, and updating the maximum count `mx` of the characters that have appeared. When the size of the window minus `mx` is greater than $k$, we need to shrink the left boundary `l` of the window, updating the count of characters within the window, until the size of the window minus `mx` is no longer greater than $k$.
63+
64+
Finally, the answer is $n - l$, where $n$ is the length of the string.
65+
66+
The time complexity is $O(n)$, and the space complexity is $O(|\Sigma|)$. Where $n$ is the length of the string, and $|\Sigma|$ is the size of the character set. In this problem, the character set is uppercase English letters, so $|\Sigma| = 26$.
5967

6068
<!-- tabs:start -->
6169

@@ -64,36 +72,32 @@ There may exists other ways to achieve this answer too.</pre>
6472
```python
6573
class Solution:
6674
def characterReplacement(self, s: str, k: int) -> int:
67-
counter = [0] * 26
68-
i = j = maxCnt = 0
69-
while i < len(s):
70-
counter[ord(s[i]) - ord('A')] += 1
71-
maxCnt = max(maxCnt, counter[ord(s[i]) - ord('A')])
72-
if i - j + 1 > maxCnt + k:
73-
counter[ord(s[j]) - ord('A')] -= 1
74-
j += 1
75-
i += 1
76-
return i - j
75+
cnt = Counter()
76+
l = mx = 0
77+
for r, c in enumerate(s):
78+
cnt[c] += 1
79+
mx = max(mx, cnt[c])
80+
if r - l + 1 - mx > k:
81+
cnt[s[l]] -= 1
82+
l += 1
83+
return len(s) - l
7784
```
7885

7986
#### Java
8087

8188
```java
8289
class Solution {
8390
public int characterReplacement(String s, int k) {
84-
int[] counter = new int[26];
85-
int i = 0;
86-
int j = 0;
87-
for (int maxCnt = 0; i < s.length(); ++i) {
88-
char c = s.charAt(i);
89-
++counter[c - 'A'];
90-
maxCnt = Math.max(maxCnt, counter[c - 'A']);
91-
if (i - j + 1 - maxCnt > k) {
92-
--counter[s.charAt(j) - 'A'];
93-
++j;
91+
int[] cnt = new int[26];
92+
int l = 0, mx = 0;
93+
int n = s.length();
94+
for (int r = 0; r < n; ++r) {
95+
mx = Math.max(mx, ++cnt[s.charAt(r) - 'A']);
96+
if (r - l + 1 - mx > k) {
97+
--cnt[s.charAt(l++) - 'A'];
9498
}
9599
}
96-
return i - j;
100+
return n - l;
97101
}
98102
}
99103
```
@@ -104,18 +108,16 @@ class Solution {
104108
class Solution {
105109
public:
106110
int characterReplacement(string s, int k) {
107-
vector<int> counter(26);
108-
int i = 0, j = 0, maxCnt = 0;
109-
for (char& c : s) {
110-
++counter[c - 'A'];
111-
maxCnt = max(maxCnt, counter[c - 'A']);
112-
if (i - j + 1 > maxCnt + k) {
113-
--counter[s[j] - 'A'];
114-
++j;
111+
int cnt[26]{};
112+
int l = 0, mx = 0;
113+
int n = s.length();
114+
for (int r = 0; r < n; ++r) {
115+
mx = max(mx, ++cnt[s[r] - 'A']);
116+
if (r - l + 1 - mx > k) {
117+
--cnt[s[l++] - 'A'];
115118
}
116-
++i;
117119
}
118-
return i - j;
120+
return n - l;
119121
}
120122
};
121123
```
@@ -124,20 +126,35 @@ public:
124126
125127
```go
126128
func characterReplacement(s string, k int) int {
127-
counter := make([]int, 26)
128-
j, maxCnt := 0, 0
129-
for i := range s {
130-
c := s[i] - 'A'
131-
counter[c]++
132-
if maxCnt < counter[c] {
133-
maxCnt = counter[c]
134-
}
135-
if i-j+1 > maxCnt+k {
136-
counter[s[j]-'A']--
137-
j++
129+
cnt := [26]int{}
130+
l, mx := 0, 0
131+
for r, c := range s {
132+
cnt[c-'A']++
133+
mx = max(mx, cnt[c-'A'])
134+
if r-l+1-mx > k {
135+
cnt[s[l]-'A']--
136+
l++
138137
}
139138
}
140-
return len(s) - j
139+
return len(s) - l
140+
}
141+
```
142+
143+
#### TypeScript
144+
145+
```ts
146+
function characterReplacement(s: string, k: number): number {
147+
const idx = (c: string) => c.charCodeAt(0) - 65;
148+
const cnt: number[] = Array(26).fill(0);
149+
const n = s.length;
150+
let [l, mx] = [0, 0];
151+
for (let r = 0; r < n; ++r) {
152+
mx = Math.max(mx, ++cnt[idx(s[r])]);
153+
if (r - l + 1 - mx > k) {
154+
--cnt[idx(s[l++])];
155+
}
156+
}
157+
return n - l;
141158
}
142159
```
143160

Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
class Solution {
22
public:
33
int characterReplacement(string s, int k) {
4-
vector<int> counter(26);
5-
int i = 0, j = 0, maxCnt = 0;
6-
for (char& c : s) {
7-
++counter[c - 'A'];
8-
maxCnt = max(maxCnt, counter[c - 'A']);
9-
if (i - j + 1 > maxCnt + k) {
10-
--counter[s[j] - 'A'];
11-
++j;
4+
int cnt[26]{};
5+
int l = 0, mx = 0;
6+
int n = s.length();
7+
for (int r = 0; r < n; ++r) {
8+
mx = max(mx, ++cnt[s[r] - 'A']);
9+
if (r - l + 1 - mx > k) {
10+
--cnt[s[l++] - 'A'];
1211
}
13-
++i;
1412
}
15-
return i - j;
13+
return n - l;
1614
}
1715
};
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
func characterReplacement(s string, k int) int {
2-
counter := make([]int, 26)
3-
j, maxCnt := 0, 0
4-
for i := range s {
5-
c := s[i] - 'A'
6-
counter[c]++
7-
if maxCnt < counter[c] {
8-
maxCnt = counter[c]
9-
}
10-
if i-j+1 > maxCnt+k {
11-
counter[s[j]-'A']--
12-
j++
2+
cnt := [26]int{}
3+
l, mx := 0, 0
4+
for r, c := range s {
5+
cnt[c-'A']++
6+
mx = max(mx, cnt[c-'A'])
7+
if r-l+1-mx > k {
8+
cnt[s[l]-'A']--
9+
l++
1310
}
1411
}
15-
return len(s) - j
12+
return len(s) - l
1613
}
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
class Solution {
22
public int characterReplacement(String s, int k) {
3-
int[] counter = new int[26];
4-
int i = 0;
5-
int j = 0;
6-
for (int maxCnt = 0; i < s.length(); ++i) {
7-
char c = s.charAt(i);
8-
++counter[c - 'A'];
9-
maxCnt = Math.max(maxCnt, counter[c - 'A']);
10-
if (i - j + 1 - maxCnt > k) {
11-
--counter[s.charAt(j) - 'A'];
12-
++j;
3+
int[] cnt = new int[26];
4+
int l = 0, mx = 0;
5+
int n = s.length();
6+
for (int r = 0; r < n; ++r) {
7+
mx = Math.max(mx, ++cnt[s.charAt(r) - 'A']);
8+
if (r - l + 1 - mx > k) {
9+
--cnt[s.charAt(l++) - 'A'];
1310
}
1411
}
15-
return i - j;
12+
return n - l;
1613
}
1714
}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
class Solution:
22
def characterReplacement(self, s: str, k: int) -> int:
3-
counter = [0] * 26
4-
i = j = maxCnt = 0
5-
while i < len(s):
6-
counter[ord(s[i]) - ord('A')] += 1
7-
maxCnt = max(maxCnt, counter[ord(s[i]) - ord('A')])
8-
if i - j + 1 > maxCnt + k:
9-
counter[ord(s[j]) - ord('A')] -= 1
10-
j += 1
11-
i += 1
12-
return i - j
3+
cnt = Counter()
4+
l = mx = 0
5+
for r, c in enumerate(s):
6+
cnt[c] += 1
7+
mx = max(mx, cnt[c])
8+
if r - l + 1 - mx > k:
9+
cnt[s[l]] -= 1
10+
l += 1
11+
return len(s) - l

0 commit comments

Comments
 (0)