Skip to content

Commit d9494c8

Browse files
authored
feat: add solutions to lc problem: No.691 (doocs#2898)
No.0691.Stickers to Spell Word
1 parent 69a86a0 commit d9494c8

File tree

7 files changed

+254
-139
lines changed

7 files changed

+254
-139
lines changed

solution/0600-0699/0691.Stickers to Spell Word/README.md

+88-46
Original file line numberDiff line numberDiff line change
@@ -69,30 +69,36 @@ tags:
6969

7070
### 方法一:BFS + 状态压缩
7171

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+
7278
<!-- tabs:start -->
7379

7480
#### Python3
7581

7682
```python
7783
class Solution:
7884
def minStickers(self, stickers: List[str], target: str) -> int:
79-
q = deque([0])
80-
ans = 0
8185
n = len(target)
86+
q = deque([0])
8287
vis = [False] * (1 << n)
8388
vis[0] = True
89+
ans = 0
8490
while q:
8591
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:
8894
return ans
8995
for s in stickers:
90-
nxt = state
9196
cnt = Counter(s)
97+
nxt = cur
9298
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:
95100
cnt[c] -= 1
101+
nxt |= 1 << i
96102
if not vis[nxt]:
97103
vis[nxt] = True
98104
q.append(nxt)
@@ -105,29 +111,28 @@ class Solution:
105111
```java
106112
class Solution {
107113
public int minStickers(String[] stickers, String target) {
114+
int n = target.length();
108115
Deque<Integer> q = new ArrayDeque<>();
109116
q.offer(0);
110-
int ans = 0;
111-
int n = target.length();
112117
boolean[] vis = new boolean[1 << n];
113118
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) {
118123
return ans;
119124
}
120125
for (String s : stickers) {
121-
int nxt = state;
122126
int[] cnt = new int[26];
127+
int nxt = cur;
123128
for (char c : s.toCharArray()) {
124129
++cnt[c - 'a'];
125130
}
126131
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];
129135
nxt |= 1 << i;
130-
--cnt[idx];
131136
}
132137
}
133138
if (!vis[nxt]) {
@@ -136,7 +141,6 @@ class Solution {
136141
}
137142
}
138143
}
139-
++ans;
140144
}
141145
return -1;
142146
}
@@ -149,25 +153,28 @@ class Solution {
149153
class Solution {
150154
public:
151155
int minStickers(vector<string>& stickers, string target) {
152-
queue<int> q{{0}};
153-
int ans = 0;
154156
int n = target.size();
157+
queue<int> q{{0}};
155158
vector<bool> vis(1 << n);
156159
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();
161163
q.pop();
164+
if (cur == (1 << n) - 1) {
165+
return ans;
166+
}
162167
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+
}
166173
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) {
169176
nxt |= 1 << i;
170-
--cnt[idx];
177+
--cnt[j];
171178
}
172179
}
173180
if (!vis[nxt]) {
@@ -176,7 +183,6 @@ public:
176183
}
177184
}
178185
}
179-
++ans;
180186
}
181187
return -1;
182188
}
@@ -186,30 +192,28 @@ public:
186192
#### Go
187193
188194
```go
189-
func minStickers(stickers []string, target string) int {
190-
q := []int{0}
195+
func minStickers(stickers []string, target string) (ans int) {
191196
n := len(target)
197+
q := []int{0}
192198
vis := make([]bool, 1<<n)
193199
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]
201203
q = q[1:]
204+
if cur == 1<<n-1 {
205+
return
206+
}
202207
for _, s := range stickers {
203-
nxt := state
204-
cnt := make([]int, 26)
208+
cnt := [26]int{}
205209
for _, c := range s {
206210
cnt[c-'a']++
207211
}
212+
nxt := cur
208213
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 {
211215
nxt |= 1 << i
212-
cnt[idx]--
216+
cnt[c-'a']--
213217
}
214218
}
215219
if !vis[nxt] {
@@ -218,12 +222,50 @@ func minStickers(stickers []string, target string) int {
218222
}
219223
}
220224
}
221-
ans++
222225
}
223226
return -1
224227
}
225228
```
226229

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+
227269
#### Rust
228270

229271
```rust

0 commit comments

Comments
 (0)