@@ -69,30 +69,36 @@ tags:
69
69
70
70
### 方法一:BFS + 状态压缩
71
71
72
+ 我们注意到,字符串 $\text{target}$ 的长度不超过 $15$,我们可以使用一个长度为 $15$ 的二进制数来表示 $\text{target}$ 的每个字符是否被拼出,如果第 $i$ 位为 $1$,表示 $\text{target}$ 的第 $i$ 个字符已经被拼出,否则表示未被拼出。
73
+
74
+ 我们定义一个初始状态 $0$,表示所有字符都未被拼出,然后我们使用广度优先搜索的方法,从初始状态开始,每次搜索时,我们枚举所有的贴纸,对于每一张贴纸,我们尝试拼出 $\text{target}$ 的每一个字符,如果拼出了某个字符,我们就将对应的二进制数的第 $i$ 位设置为 $1$,表示该字符已经被拼出,然后我们继续搜索,直到我们拼出了 $\text{target}$ 的所有字符。
75
+
76
+ 时间复杂度 $O(2^n \times m \times (l + n))$,空间复杂度 $O(2^n)$。其中 $n$ 是字符串 $\text{target}$ 的长度,而 $m$ 和 $l$ 分别是贴纸的数量和贴纸的平均长度。
77
+
72
78
<!-- tabs:start -->
73
79
74
80
#### Python3
75
81
76
82
``` python
77
83
class Solution :
78
84
def minStickers (self , stickers : List[str ], target : str ) -> int :
79
- q = deque([0 ])
80
- ans = 0
81
85
n = len (target)
86
+ q = deque([0 ])
82
87
vis = [False ] * (1 << n)
83
88
vis[0 ] = True
89
+ ans = 0
84
90
while q:
85
91
for _ in range (len (q)):
86
- state = q.popleft()
87
- if state == (1 << n) - 1 :
92
+ cur = q.popleft()
93
+ if cur == (1 << n) - 1 :
88
94
return ans
89
95
for s in stickers:
90
- nxt = state
91
96
cnt = Counter(s)
97
+ nxt = cur
92
98
for i, c in enumerate (target):
93
- if not (nxt & (1 << i)) and cnt[c]:
94
- nxt |= 1 << i
99
+ if (cur >> i & 1 ) == 0 and cnt[c] > 0 :
95
100
cnt[c] -= 1
101
+ nxt |= 1 << i
96
102
if not vis[nxt]:
97
103
vis[nxt] = True
98
104
q.append(nxt)
@@ -105,29 +111,28 @@ class Solution:
105
111
``` java
106
112
class Solution {
107
113
public int minStickers (String [] stickers , String target ) {
114
+ int n = target. length();
108
115
Deque<Integer > q = new ArrayDeque<> ();
109
116
q. offer(0 );
110
- int ans = 0 ;
111
- int n = target. length();
112
117
boolean [] vis = new boolean [1 << n];
113
118
vis[0 ] = true ;
114
- while ( ! q. isEmpty()) {
115
- for (int t = q. size(); t > 0 ; -- t ) {
116
- int state = q. poll();
117
- if (state == (1 << n) - 1 ) {
119
+ for ( int ans = 0 ; ! q. isEmpty(); ++ ans ) {
120
+ for (int m = q. size(); m > 0 ; -- m ) {
121
+ int cur = q. poll();
122
+ if (cur == (1 << n) - 1 ) {
118
123
return ans;
119
124
}
120
125
for (String s : stickers) {
121
- int nxt = state;
122
126
int [] cnt = new int [26 ];
127
+ int nxt = cur;
123
128
for (char c : s. toCharArray()) {
124
129
++ cnt[c - ' a' ];
125
130
}
126
131
for (int i = 0 ; i < n; ++ i) {
127
- int idx = target. charAt(i) - ' a' ;
128
- if ((nxt & (1 << i)) == 0 && cnt[idx] > 0 ) {
132
+ int j = target. charAt(i) - ' a' ;
133
+ if ((cur >> i & 1 ) == 0 && cnt[j] > 0 ) {
134
+ -- cnt[j];
129
135
nxt |= 1 << i;
130
- -- cnt[idx];
131
136
}
132
137
}
133
138
if (! vis[nxt]) {
@@ -136,7 +141,6 @@ class Solution {
136
141
}
137
142
}
138
143
}
139
- ++ ans;
140
144
}
141
145
return - 1 ;
142
146
}
@@ -149,25 +153,28 @@ class Solution {
149
153
class Solution {
150
154
public:
151
155
int minStickers(vector<string >& stickers, string target) {
152
- queue<int > q{{0}};
153
- int ans = 0;
154
156
int n = target.size();
157
+ queue<int > q{{0}};
155
158
vector<bool > vis(1 << n);
156
159
vis[ 0] = true;
157
- while (!q.empty()) {
158
- for (int t = q.size(); t; --t) {
159
- int state = q.front();
160
- if (state == (1 << n) - 1) return ans;
160
+ for (int ans = 0; q.size(); ++ans) {
161
+ for (int m = q.size(); m; --m) {
162
+ int cur = q.front();
161
163
q.pop();
164
+ if (cur == (1 << n) - 1) {
165
+ return ans;
166
+ }
162
167
for (auto& s : stickers) {
163
- int nxt = state;
164
- vector<int > cnt(26);
165
- for (char& c : s) ++cnt[ c - 'a'] ;
168
+ int cnt[ 26] {};
169
+ int nxt = cur;
170
+ for (char& c : s) {
171
+ ++cnt[ c - 'a'] ;
172
+ }
166
173
for (int i = 0; i < n; ++i) {
167
- int idx = target[ i] - 'a';
168
- if (!(nxt & (1 << i)) && cnt[ idx ] ) {
174
+ int j = target[ i] - 'a';
175
+ if ((cur >> i & 1) == 0 && cnt[ j ] > 0 ) {
169
176
nxt |= 1 << i;
170
- --cnt[ idx ] ;
177
+ --cnt[ j ] ;
171
178
}
172
179
}
173
180
if (!vis[ nxt] ) {
@@ -176,7 +183,6 @@ public:
176
183
}
177
184
}
178
185
}
179
- ++ans;
180
186
}
181
187
return -1;
182
188
}
@@ -186,30 +192,28 @@ public:
186
192
#### Go
187
193
188
194
```go
189
- func minStickers(stickers []string, target string) int {
190
- q := []int{0}
195
+ func minStickers(stickers []string, target string) (ans int) {
191
196
n := len(target)
197
+ q := []int{0}
192
198
vis := make([]bool, 1<<n)
193
199
vis[0] = true
194
- ans := 0
195
- for len(q) > 0 {
196
- for t := len(q); t > 0; t-- {
197
- state := q[0]
198
- if state == (1<<n)-1 {
199
- return ans
200
- }
200
+ for ; len(q) > 0; ans++ {
201
+ for m := len(q); m > 0; m-- {
202
+ cur := q[0]
201
203
q = q[1:]
204
+ if cur == 1<<n-1 {
205
+ return
206
+ }
202
207
for _, s := range stickers {
203
- nxt := state
204
- cnt := make([]int, 26)
208
+ cnt := [26]int{}
205
209
for _, c := range s {
206
210
cnt[c-'a']++
207
211
}
212
+ nxt := cur
208
213
for i, c := range target {
209
- idx := c - 'a'
210
- if (nxt&(1<<i)) == 0 && cnt[idx] > 0 {
214
+ if cur>>i&1 == 0 && cnt[c-'a'] > 0 {
211
215
nxt |= 1 << i
212
- cnt[idx ]--
216
+ cnt[c-'a' ]--
213
217
}
214
218
}
215
219
if !vis[nxt] {
@@ -218,12 +222,50 @@ func minStickers(stickers []string, target string) int {
218
222
}
219
223
}
220
224
}
221
- ans++
222
225
}
223
226
return -1
224
227
}
225
228
```
226
229
230
+ #### TypeScript
231
+
232
+ ``` ts
233
+ function minStickers(stickers : string [], target : string ): number {
234
+ const n = target .length ;
235
+ const q: number [] = [0 ];
236
+ const vis: boolean [] = Array (1 << n ).fill (false );
237
+ vis [0 ] = true ;
238
+ for (let ans = 0 ; q .length ; ++ ans ) {
239
+ const qq: number [] = [];
240
+ for (const cur of q ) {
241
+ if (cur === (1 << n ) - 1 ) {
242
+ return ans ;
243
+ }
244
+ for (const s of stickers ) {
245
+ const cnt: number [] = Array (26 ).fill (0 );
246
+ for (const c of s ) {
247
+ cnt [c .charCodeAt (0 ) - 97 ]++ ;
248
+ }
249
+ let nxt = cur ;
250
+ for (let i = 0 ; i < n ; ++ i ) {
251
+ const j = target .charCodeAt (i ) - 97 ;
252
+ if (((cur >> i ) & 1 ) === 0 && cnt [j ]) {
253
+ nxt |= 1 << i ;
254
+ cnt [j ]-- ;
255
+ }
256
+ }
257
+ if (! vis [nxt ]) {
258
+ vis [nxt ] = true ;
259
+ qq .push (nxt );
260
+ }
261
+ }
262
+ }
263
+ q .splice (0 , q .length , ... qq );
264
+ }
265
+ return - 1 ;
266
+ }
267
+ ```
268
+
227
269
#### Rust
228
270
229
271
``` rust
0 commit comments