Skip to content

Commit 6724a40

Browse files
authored
feat: add solutions to lc problem: No.2405 (#3522)
No.2405.Optimal Partition of String
1 parent f46ff73 commit 6724a40

File tree

12 files changed

+128
-345
lines changed

12 files changed

+128
-345
lines changed

solution/2400-2499/2405.Optimal Partition of String/README.md

+44-125
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,15 @@ tags:
6464

6565
### 方法一:贪心
6666

67-
根据题意,每个子字符串应该尽可能长,且包含的字符唯一我们只需要贪心地进行划分即可。
67+
根据题意,每个子字符串应该尽可能长,且包含的字符唯一,因此,我们只需要贪心地进行划分即可。
6868

69-
过程中,可以用哈希表记录当前子字符串的所有字符,空间复杂度 $O(n)$;也可以使用一个数字,用位运算的方式记录字符,空间复杂度 $O(1)$。
69+
我们定义一个二进制整数 $\textit{mask}$ 来记录当前子字符串中出现的字符,其中 $\textit{mask}$ 的第 $i$ 位为 $1$ 表示第 $i$ 个字母已经出现过,为 $0$ 表示未出现过。另外,我们还需要一个变量 $\textit{ans}$ 来记录划分的子字符串个数,初始时 $\textit{ans} = 1$。
7070

71-
时间复杂度 $O(n)$。其中 $n$ 是字符串 $s$ 的长度。
71+
遍历字符串 $s$ 中的每个字符,对于每个字符 $c$,我们将其转换为 $0$ 到 $25$ 之间的整数 $x$,然后判断 $\textit{mask}$ 的第 $x$ 位是否为 $1$,如果为 $1$,说明当前字符 $c$ 与当前子字符串中的字符有重复,此时 $\textit{ans}$ 需要加 $1$,并将 $\textit{mask}$ 置为 $0$;否则,将 $\textit{mask}$ 的第 $x$ 位置为 $1$。然后,我们将 $\textit{mask}$ 更新为 $\textit{mask}$ 与 $2^x$ 的按位或结果。
72+
73+
最后,返回 $\textit{ans}$ 即可。
74+
75+
时间复杂度 $O(n)$,其中 $n$ 为字符串 $s$ 的长度。空间复杂度 $O(1)$。
7276

7377
<!-- tabs:start -->
7478

@@ -77,13 +81,12 @@ tags:
7781
```python
7882
class Solution:
7983
def partitionString(self, s: str) -> int:
80-
ss = set()
81-
ans = 1
82-
for c in s:
83-
if c in ss:
84+
ans, mask = 1, 0
85+
for x in map(lambda c: ord(c) - ord("a"), s):
86+
if mask >> x & 1:
8487
ans += 1
85-
ss = set()
86-
ss.add(c)
88+
mask = 0
89+
mask |= 1 << x
8790
return ans
8891
```
8992

@@ -92,14 +95,14 @@ class Solution:
9295
```java
9396
class Solution {
9497
public int partitionString(String s) {
95-
Set<Character> ss = new HashSet<>();
96-
int ans = 1;
97-
for (char c : s.toCharArray()) {
98-
if (ss.contains(c)) {
98+
int ans = 1, mask = 0;
99+
for (int i = 0; i < s.length(); ++i) {
100+
int x = s.charAt(i) - 'a';
101+
if ((mask >> x & 1) == 1) {
99102
++ans;
100-
ss.clear();
103+
mask = 0;
101104
}
102-
ss.add(c);
105+
mask |= 1 << x;
103106
}
104107
return ans;
105108
}
@@ -112,14 +115,14 @@ class Solution {
112115
class Solution {
113116
public:
114117
int partitionString(string s) {
115-
unordered_set<char> ss;
116-
int ans = 1;
117-
for (char c : s) {
118-
if (ss.count(c)) {
118+
int ans = 1, mask = 0;
119+
for (char& c : s) {
120+
int x = c - 'a';
121+
if (mask >> x & 1) {
119122
++ans;
120-
ss.clear();
123+
mask = 0;
121124
}
122-
ss.insert(c);
125+
mask |= 1 << x;
123126
}
124127
return ans;
125128
}
@@ -130,14 +133,14 @@ public:
130133
131134
```go
132135
func partitionString(s string) int {
133-
ss := map[rune]bool{}
134-
ans := 1
136+
ans, mask := 1, 0
135137
for _, c := range s {
136-
if ss[c] {
138+
x := int(c - 'a')
139+
if mask>>x&1 == 1 {
137140
ans++
138-
ss = map[rune]bool{}
141+
mask = 0
139142
}
140-
ss[c] = true
143+
mask |= 1 << x
141144
}
142145
return ans
143146
}
@@ -147,35 +150,34 @@ func partitionString(s string) int {
147150

148151
```ts
149152
function partitionString(s: string): number {
150-
const set = new Set();
151-
let res = 1;
153+
let [ans, mask] = [1, 0];
152154
for (const c of s) {
153-
if (set.has(c)) {
154-
res++;
155-
set.clear();
155+
const x = c.charCodeAt(0) - 97;
156+
if ((mask >> x) & 1) {
157+
++ans;
158+
mask = 0;
156159
}
157-
set.add(c);
160+
mask |= 1 << x;
158161
}
159-
return res;
162+
return ans;
160163
}
161164
```
162165

163166
#### Rust
164167

165168
```rust
166-
use std::collections::HashSet;
167169
impl Solution {
168170
pub fn partition_string(s: String) -> i32 {
169-
let mut set = HashSet::new();
170-
let mut res = 1;
171-
for c in s.as_bytes().iter() {
172-
if set.contains(c) {
173-
res += 1;
174-
set.clear();
171+
let mut ans = 1;
172+
let mut mask = 0;
173+
for x in s.chars().map(|c| (c as u8 - b'a') as u32) {
174+
if mask >> x & 1 == 1 {
175+
ans += 1;
176+
mask = 0;
175177
}
176-
set.insert(c);
178+
mask |= 1 << x;
177179
}
178-
res
180+
ans
179181
}
180182
}
181183
```
@@ -184,87 +186,4 @@ impl Solution {
184186

185187
<!-- solution:end -->
186188

187-
<!-- solution:start -->
188-
189-
### 方法二
190-
191-
<!-- tabs:start -->
192-
193-
#### Python3
194-
195-
```python
196-
class Solution:
197-
def partitionString(self, s: str) -> int:
198-
ans, v = 1, 0
199-
for c in s:
200-
i = ord(c) - ord('a')
201-
if (v >> i) & 1:
202-
v = 0
203-
ans += 1
204-
v |= 1 << i
205-
return ans
206-
```
207-
208-
#### Java
209-
210-
```java
211-
class Solution {
212-
public int partitionString(String s) {
213-
int v = 0;
214-
int ans = 1;
215-
for (char c : s.toCharArray()) {
216-
int i = c - 'a';
217-
if (((v >> i) & 1) == 1) {
218-
v = 0;
219-
++ans;
220-
}
221-
v |= 1 << i;
222-
}
223-
return ans;
224-
}
225-
}
226-
```
227-
228-
#### C++
229-
230-
```cpp
231-
class Solution {
232-
public:
233-
int partitionString(string s) {
234-
int ans = 1;
235-
int v = 0;
236-
for (char c : s) {
237-
int i = c - 'a';
238-
if ((v >> i) & 1) {
239-
v = 0;
240-
++ans;
241-
}
242-
v |= 1 << i;
243-
}
244-
return ans;
245-
}
246-
};
247-
```
248-
249-
#### Go
250-
251-
```go
252-
func partitionString(s string) int {
253-
ans, v := 1, 0
254-
for _, c := range s {
255-
i := int(c - 'a')
256-
if v>>i&1 == 1 {
257-
v = 0
258-
ans++
259-
}
260-
v |= 1 << i
261-
}
262-
return ans
263-
}
264-
```
265-
266-
<!-- tabs:end -->
267-
268-
<!-- solution:end -->
269-
270189
<!-- problem:end -->

0 commit comments

Comments
 (0)