Skip to content

Commit d734bdd

Browse files
committed
feat: add solutions to lc problem: No.2423
No.2423.Remove Letter To Equalize Frequency
1 parent 054a684 commit d734bdd

File tree

7 files changed

+274
-168
lines changed

7 files changed

+274
-168
lines changed

Diff for: solution/2400-2499/2423.Remove Letter To Equalize Frequency/README.md

+96-58
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,15 @@
4646

4747
<!-- 这里可写通用的实现逻辑 -->
4848

49-
**方法一:直接模拟**
49+
**方法一:计数 + 枚举**
5050

51-
遍历字符串中的每个字符,删除该字符后,判断剩余字符串中每个字符出现的频率是否相同。如果相同,返回 `true`,否则遍历结束,返回 `false`
51+
我们先用哈希表或者一个长度为 $26$ 的数组 $cnt$ 统计字符串中每个字母出现的次数
5252

53-
时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 为字符串的长度。
53+
接下来,枚举 $26$ 个字母,如果字母 $c$ 在字符串中出现过,我们将其出现次数减一,然后判断剩余的字母出现次数是否相同。如果相同,返回 `true`,否则将 $c$ 的出现次数加一,继续枚举下一个字母。
54+
55+
枚举结束,说明无法通过删除一个字母使得剩余字母出现次数相同,返回 `false`
56+
57+
时间复杂度 $O(n + C^2)$,空间复杂度 $O(C)$,其中 $n$ 为字符串 $word$ 的长度,而 $C$ 为字符集的大小,本题中 $C = 26$。
5458

5559
<!-- tabs:start -->
5660

@@ -61,10 +65,12 @@
6165
```python
6266
class Solution:
6367
def equalFrequency(self, word: str) -> bool:
64-
for i in range(len(word)):
65-
cnt = Counter(word[:i] + word[i + 1:])
66-
if len(set(cnt.values())) == 1:
68+
cnt = Counter(word)
69+
for c in cnt.keys():
70+
cnt[c] -= 1
71+
if len(set(v for v in cnt.values() if v)) == 1:
6772
return True
73+
cnt[c] += 1
6874
return False
6975
```
7076

@@ -75,21 +81,29 @@ class Solution:
7581
```java
7682
class Solution {
7783
public boolean equalFrequency(String word) {
84+
int[] cnt = new int[26];
7885
for (int i = 0; i < word.length(); ++i) {
79-
int[] cnt = new int[26];
80-
for (int j = 0; j < word.length(); ++j) {
81-
if (j != i) {
82-
++cnt[word.charAt(j) - 'a'];
86+
++cnt[word.charAt(i) - 'a'];
87+
}
88+
for (int i = 0; i < 26; ++i) {
89+
if (cnt[i] > 0) {
90+
--cnt[i];
91+
int x = 0;
92+
boolean ok = true;
93+
for (int v : cnt) {
94+
if (v == 0) {
95+
continue;
96+
}
97+
if (x > 0 && v != x) {
98+
ok = false;
99+
break;
100+
}
101+
x = v;
83102
}
84-
}
85-
Set<Integer> vis = new HashSet<>();
86-
for (int v : cnt) {
87-
if (v > 0) {
88-
vis.add(v);
103+
if (ok) {
104+
return true;
89105
}
90-
}
91-
if (vis.size() == 1) {
92-
return true;
106+
++cnt[i];
93107
}
94108
}
95109
return false;
@@ -103,21 +117,29 @@ class Solution {
103117
class Solution {
104118
public:
105119
bool equalFrequency(string word) {
106-
for (int i = 0; i < word.size(); ++i) {
107-
int cnt[26] = {0};
108-
for (int j = 0; j < word.size(); ++j) {
109-
if (j != i) {
110-
++cnt[word[j] - 'a'];
120+
int cnt[26]{};
121+
for (char& c : word) {
122+
++cnt[c - 'a'];
123+
}
124+
for (int i = 0; i < 26; ++i) {
125+
if (cnt[i]) {
126+
--cnt[i];
127+
int x = 0;
128+
bool ok = true;
129+
for (int v : cnt) {
130+
if (v == 0) {
131+
continue;
132+
}
133+
if (x && v != x) {
134+
ok = false;
135+
break;
136+
}
137+
x = v;
111138
}
112-
}
113-
unordered_set<int> vis;
114-
for (int v : cnt) {
115-
if (v) {
116-
vis.insert(v);
139+
if (ok) {
140+
return true;
117141
}
118-
}
119-
if (vis.size() == 1) {
120-
return true;
142+
++cnt[i];
121143
}
122144
}
123145
return false;
@@ -129,21 +151,29 @@ public:
129151
130152
```go
131153
func equalFrequency(word string) bool {
132-
for i := range word {
133-
cnt := make([]int, 26)
134-
for j, c := range word {
135-
if j != i {
136-
cnt[c-'a']++
154+
cnt := [26]int{}
155+
for _, c := range word {
156+
cnt[c-'a']++
157+
}
158+
for i := range cnt {
159+
if cnt[i] > 0 {
160+
cnt[i]--
161+
x := 0
162+
ok := true
163+
for _, v := range cnt {
164+
if v == 0 {
165+
continue
166+
}
167+
if x > 0 && v != x {
168+
ok = false
169+
break
170+
}
171+
x = v
137172
}
138-
}
139-
vis := map[int]bool{}
140-
for _, v := range cnt {
141-
if v > 0 {
142-
vis[v] = true
173+
if ok {
174+
return true
143175
}
144-
}
145-
if len(vis) == 1 {
146-
return true
176+
cnt[i]++
147177
}
148178
}
149179
return false
@@ -154,22 +184,30 @@ func equalFrequency(word string) bool {
154184

155185
```ts
156186
function equalFrequency(word: string): boolean {
157-
const map = new Map();
187+
const cnt: number[] = new Array(26).fill(0);
158188
for (const c of word) {
159-
map.set(c, (map.get(c) ?? 0) + 1);
160-
}
161-
const count = new Map();
162-
for (const v of map.values()) {
163-
count.set(v, (count.get(v) ?? 0) + 1);
189+
cnt[c.charCodeAt(0) - 97]++;
164190
}
165-
if (count.size === 1) {
166-
return map.size == 1 || [...count.keys()][0] === 1;
167-
}
168-
if (count.size === 2) {
169-
return [...count.entries()].some(
170-
(v, i, arr) =>
171-
(v[0] === 1 || v[0] - arr[i ^ 1][0] === 1) && v[1] === 1,
172-
);
191+
for (let i = 0; i < 26; ++i) {
192+
if (cnt[i]) {
193+
cnt[i]--;
194+
let x = 0;
195+
let ok = true;
196+
for (const v of cnt) {
197+
if (v === 0) {
198+
continue;
199+
}
200+
if (x && v !== x) {
201+
ok = false;
202+
break;
203+
}
204+
x = v;
205+
}
206+
if (ok) {
207+
return true;
208+
}
209+
cnt[i]++;
210+
}
173211
}
174212
return false;
175213
}

Diff for: solution/2400-2499/2423.Remove Letter To Equalize Frequency/README_EN.md

+89-55
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,12 @@
4949
```python
5050
class Solution:
5151
def equalFrequency(self, word: str) -> bool:
52-
for i in range(len(word)):
53-
cnt = Counter(word[:i] + word[i + 1:])
54-
if len(set(cnt.values())) == 1:
52+
cnt = Counter(word)
53+
for c in cnt.keys():
54+
cnt[c] -= 1
55+
if len(set(v for v in cnt.values() if v)) == 1:
5556
return True
57+
cnt[c] += 1
5658
return False
5759
```
5860

@@ -61,21 +63,29 @@ class Solution:
6163
```java
6264
class Solution {
6365
public boolean equalFrequency(String word) {
66+
int[] cnt = new int[26];
6467
for (int i = 0; i < word.length(); ++i) {
65-
int[] cnt = new int[26];
66-
for (int j = 0; j < word.length(); ++j) {
67-
if (j != i) {
68-
++cnt[word.charAt(j) - 'a'];
68+
++cnt[word.charAt(i) - 'a'];
69+
}
70+
for (int i = 0; i < 26; ++i) {
71+
if (cnt[i] > 0) {
72+
--cnt[i];
73+
int x = 0;
74+
boolean ok = true;
75+
for (int v : cnt) {
76+
if (v == 0) {
77+
continue;
78+
}
79+
if (x > 0 && v != x) {
80+
ok = false;
81+
break;
82+
}
83+
x = v;
6984
}
70-
}
71-
Set<Integer> vis = new HashSet<>();
72-
for (int v : cnt) {
73-
if (v > 0) {
74-
vis.add(v);
85+
if (ok) {
86+
return true;
7587
}
76-
}
77-
if (vis.size() == 1) {
78-
return true;
88+
++cnt[i];
7989
}
8090
}
8191
return false;
@@ -89,21 +99,29 @@ class Solution {
8999
class Solution {
90100
public:
91101
bool equalFrequency(string word) {
92-
for (int i = 0; i < word.size(); ++i) {
93-
int cnt[26] = {0};
94-
for (int j = 0; j < word.size(); ++j) {
95-
if (j != i) {
96-
++cnt[word[j] - 'a'];
102+
int cnt[26]{};
103+
for (char& c : word) {
104+
++cnt[c - 'a'];
105+
}
106+
for (int i = 0; i < 26; ++i) {
107+
if (cnt[i]) {
108+
--cnt[i];
109+
int x = 0;
110+
bool ok = true;
111+
for (int v : cnt) {
112+
if (v == 0) {
113+
continue;
114+
}
115+
if (x && v != x) {
116+
ok = false;
117+
break;
118+
}
119+
x = v;
97120
}
98-
}
99-
unordered_set<int> vis;
100-
for (int v : cnt) {
101-
if (v) {
102-
vis.insert(v);
121+
if (ok) {
122+
return true;
103123
}
104-
}
105-
if (vis.size() == 1) {
106-
return true;
124+
++cnt[i];
107125
}
108126
}
109127
return false;
@@ -115,21 +133,29 @@ public:
115133
116134
```go
117135
func equalFrequency(word string) bool {
118-
for i := range word {
119-
cnt := make([]int, 26)
120-
for j, c := range word {
121-
if j != i {
122-
cnt[c-'a']++
136+
cnt := [26]int{}
137+
for _, c := range word {
138+
cnt[c-'a']++
139+
}
140+
for i := range cnt {
141+
if cnt[i] > 0 {
142+
cnt[i]--
143+
x := 0
144+
ok := true
145+
for _, v := range cnt {
146+
if v == 0 {
147+
continue
148+
}
149+
if x > 0 && v != x {
150+
ok = false
151+
break
152+
}
153+
x = v
123154
}
124-
}
125-
vis := map[int]bool{}
126-
for _, v := range cnt {
127-
if v > 0 {
128-
vis[v] = true
155+
if ok {
156+
return true
129157
}
130-
}
131-
if len(vis) == 1 {
132-
return true
158+
cnt[i]++
133159
}
134160
}
135161
return false
@@ -140,22 +166,30 @@ func equalFrequency(word string) bool {
140166

141167
```ts
142168
function equalFrequency(word: string): boolean {
143-
const map = new Map();
169+
const cnt: number[] = new Array(26).fill(0);
144170
for (const c of word) {
145-
map.set(c, (map.get(c) ?? 0) + 1);
146-
}
147-
const count = new Map();
148-
for (const v of map.values()) {
149-
count.set(v, (count.get(v) ?? 0) + 1);
150-
}
151-
if (count.size === 1) {
152-
return map.size == 1 || [...count.keys()][0] === 1;
171+
cnt[c.charCodeAt(0) - 97]++;
153172
}
154-
if (count.size === 2) {
155-
return [...count.entries()].some(
156-
(v, i, arr) =>
157-
(v[0] === 1 || v[0] - arr[i ^ 1][0] === 1) && v[1] === 1,
158-
);
173+
for (let i = 0; i < 26; ++i) {
174+
if (cnt[i]) {
175+
cnt[i]--;
176+
let x = 0;
177+
let ok = true;
178+
for (const v of cnt) {
179+
if (v === 0) {
180+
continue;
181+
}
182+
if (x && v !== x) {
183+
ok = false;
184+
break;
185+
}
186+
x = v;
187+
}
188+
if (ok) {
189+
return true;
190+
}
191+
cnt[i]++;
192+
}
159193
}
160194
return false;
161195
}

0 commit comments

Comments
 (0)