@@ -64,11 +64,15 @@ tags:
64
64
65
65
### 方法一:贪心
66
66
67
- 根据题意,每个子字符串应该尽可能长,且包含的字符唯一。 我们只需要贪心地进行划分即可。
67
+ 根据题意,每个子字符串应该尽可能长,且包含的字符唯一,因此, 我们只需要贪心地进行划分即可。
68
68
69
- 过程中,可以用哈希表记录当前子字符串的所有字符,空间复杂度 $O(n)$;也可以使用一个数字,用位运算的方式记录字符,空间复杂度 $O(1) $。
69
+ 我们定义一个二进制整数 $\textit{mask}$ 来记录当前子字符串中出现的字符,其中 $\textit{mask}$ 的第 $i$ 位为 $1$ 表示第 $i$ 个字母已经出现过,为 $0$ 表示未出现过。另外,我们还需要一个变量 $\textit{ans}$ 来记录划分的子字符串个数,初始时 $\textit{ans} = 1 $。
70
70
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)$。
72
76
73
77
<!-- tabs:start -->
74
78
@@ -77,13 +81,12 @@ tags:
77
81
``` python
78
82
class Solution :
79
83
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 :
84
87
ans += 1
85
- ss = set ()
86
- ss.add(c)
88
+ mask = 0
89
+ mask |= 1 << x
87
90
return ans
88
91
```
89
92
@@ -92,14 +95,14 @@ class Solution:
92
95
``` java
93
96
class Solution {
94
97
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 ) {
99
102
++ ans;
100
- ss . clear() ;
103
+ mask = 0 ;
101
104
}
102
- ss . add(c) ;
105
+ mask |= 1 << x ;
103
106
}
104
107
return ans;
105
108
}
@@ -112,14 +115,14 @@ class Solution {
112
115
class Solution {
113
116
public:
114
117
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 ) {
119
122
++ans;
120
- ss.clear() ;
123
+ mask = 0 ;
121
124
}
122
- ss.insert(c) ;
125
+ mask |= 1 << x ;
123
126
}
124
127
return ans;
125
128
}
@@ -130,14 +133,14 @@ public:
130
133
131
134
```go
132
135
func partitionString(s string) int {
133
- ss := map[rune]bool{}
134
- ans := 1
136
+ ans, mask := 1, 0
135
137
for _, c := range s {
136
- if ss[c] {
138
+ x := int(c - 'a')
139
+ if mask>>x&1 == 1 {
137
140
ans++
138
- ss = map[rune]bool{}
141
+ mask = 0
139
142
}
140
- ss[c] = true
143
+ mask |= 1 << x
141
144
}
142
145
return ans
143
146
}
@@ -147,35 +150,34 @@ func partitionString(s string) int {
147
150
148
151
``` ts
149
152
function partitionString(s : string ): number {
150
- const set = new Set ();
151
- let res = 1 ;
153
+ let [ans, mask] = [1 , 0 ];
152
154
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 ;
156
159
}
157
- set . add ( c ) ;
160
+ mask |= 1 << x ;
158
161
}
159
- return res ;
162
+ return ans ;
160
163
}
161
164
```
162
165
163
166
#### Rust
164
167
165
168
``` rust
166
- use std :: collections :: HashSet ;
167
169
impl Solution {
168
170
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 ;
175
177
}
176
- set . insert ( c ) ;
178
+ mask |= 1 << x ;
177
179
}
178
- res
180
+ ans
179
181
}
180
182
}
181
183
```
@@ -184,87 +186,4 @@ impl Solution {
184
186
185
187
<!-- solution: end -->
186
188
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
-
270
189
<!-- problem: end -->
0 commit comments