@@ -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
7882class 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
9396class 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 {
112115class Solution {
113116public:
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
132135func 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
149152function 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 ;
167169impl 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