Skip to content

feat: add solutions to lc problem: No.691 #2898

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 88 additions & 46 deletions solution/0600-0699/0691.Stickers to Spell Word/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,30 +69,36 @@ tags:

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

我们注意到,字符串 $\text{target}$ 的长度不超过 $15$,我们可以使用一个长度为 $15$ 的二进制数来表示 $\text{target}$ 的每个字符是否被拼出,如果第 $i$ 位为 $1$,表示 $\text{target}$ 的第 $i$ 个字符已经被拼出,否则表示未被拼出。

我们定义一个初始状态 $0$,表示所有字符都未被拼出,然后我们使用广度优先搜索的方法,从初始状态开始,每次搜索时,我们枚举所有的贴纸,对于每一张贴纸,我们尝试拼出 $\text{target}$ 的每一个字符,如果拼出了某个字符,我们就将对应的二进制数的第 $i$ 位设置为 $1$,表示该字符已经被拼出,然后我们继续搜索,直到我们拼出了 $\text{target}$ 的所有字符。

时间复杂度 $O(2^n \times m \times (l + n))$,空间复杂度 $O(2^n)$。其中 $n$ 是字符串 $\text{target}$ 的长度,而 $m$ 和 $l$ 分别是贴纸的数量和贴纸的平均长度。

<!-- tabs:start -->

#### Python3

```python
class Solution:
def minStickers(self, stickers: List[str], target: str) -> int:
q = deque([0])
ans = 0
n = len(target)
q = deque([0])
vis = [False] * (1 << n)
vis[0] = True
ans = 0
while q:
for _ in range(len(q)):
state = q.popleft()
if state == (1 << n) - 1:
cur = q.popleft()
if cur == (1 << n) - 1:
return ans
for s in stickers:
nxt = state
cnt = Counter(s)
nxt = cur
for i, c in enumerate(target):
if not (nxt & (1 << i)) and cnt[c]:
nxt |= 1 << i
if (cur >> i & 1) == 0 and cnt[c] > 0:
cnt[c] -= 1
nxt |= 1 << i
if not vis[nxt]:
vis[nxt] = True
q.append(nxt)
Expand All @@ -105,29 +111,28 @@ class Solution:
```java
class Solution {
public int minStickers(String[] stickers, String target) {
int n = target.length();
Deque<Integer> q = new ArrayDeque<>();
q.offer(0);
int ans = 0;
int n = target.length();
boolean[] vis = new boolean[1 << n];
vis[0] = true;
while (!q.isEmpty()) {
for (int t = q.size(); t > 0; --t) {
int state = q.poll();
if (state == (1 << n) - 1) {
for (int ans = 0; !q.isEmpty(); ++ans) {
for (int m = q.size(); m > 0; --m) {
int cur = q.poll();
if (cur == (1 << n) - 1) {
return ans;
}
for (String s : stickers) {
int nxt = state;
int[] cnt = new int[26];
int nxt = cur;
for (char c : s.toCharArray()) {
++cnt[c - 'a'];
}
for (int i = 0; i < n; ++i) {
int idx = target.charAt(i) - 'a';
if ((nxt & (1 << i)) == 0 && cnt[idx] > 0) {
int j = target.charAt(i) - 'a';
if ((cur >> i & 1) == 0 && cnt[j] > 0) {
--cnt[j];
nxt |= 1 << i;
--cnt[idx];
}
}
if (!vis[nxt]) {
Expand All @@ -136,7 +141,6 @@ class Solution {
}
}
}
++ans;
}
return -1;
}
Expand All @@ -149,25 +153,28 @@ class Solution {
class Solution {
public:
int minStickers(vector<string>& stickers, string target) {
queue<int> q{{0}};
int ans = 0;
int n = target.size();
queue<int> q{{0}};
vector<bool> vis(1 << n);
vis[0] = true;
while (!q.empty()) {
for (int t = q.size(); t; --t) {
int state = q.front();
if (state == (1 << n) - 1) return ans;
for (int ans = 0; q.size(); ++ans) {
for (int m = q.size(); m; --m) {
int cur = q.front();
q.pop();
if (cur == (1 << n) - 1) {
return ans;
}
for (auto& s : stickers) {
int nxt = state;
vector<int> cnt(26);
for (char& c : s) ++cnt[c - 'a'];
int cnt[26]{};
int nxt = cur;
for (char& c : s) {
++cnt[c - 'a'];
}
for (int i = 0; i < n; ++i) {
int idx = target[i] - 'a';
if (!(nxt & (1 << i)) && cnt[idx]) {
int j = target[i] - 'a';
if ((cur >> i & 1) == 0 && cnt[j] > 0) {
nxt |= 1 << i;
--cnt[idx];
--cnt[j];
}
}
if (!vis[nxt]) {
Expand All @@ -176,7 +183,6 @@ public:
}
}
}
++ans;
}
return -1;
}
Expand All @@ -186,30 +192,28 @@ public:
#### Go

```go
func minStickers(stickers []string, target string) int {
q := []int{0}
func minStickers(stickers []string, target string) (ans int) {
n := len(target)
q := []int{0}
vis := make([]bool, 1<<n)
vis[0] = true
ans := 0
for len(q) > 0 {
for t := len(q); t > 0; t-- {
state := q[0]
if state == (1<<n)-1 {
return ans
}
for ; len(q) > 0; ans++ {
for m := len(q); m > 0; m-- {
cur := q[0]
q = q[1:]
if cur == 1<<n-1 {
return
}
for _, s := range stickers {
nxt := state
cnt := make([]int, 26)
cnt := [26]int{}
for _, c := range s {
cnt[c-'a']++
}
nxt := cur
for i, c := range target {
idx := c - 'a'
if (nxt&(1<<i)) == 0 && cnt[idx] > 0 {
if cur>>i&1 == 0 && cnt[c-'a'] > 0 {
nxt |= 1 << i
cnt[idx]--
cnt[c-'a']--
}
}
if !vis[nxt] {
Expand All @@ -218,12 +222,50 @@ func minStickers(stickers []string, target string) int {
}
}
}
ans++
}
return -1
}
```

#### TypeScript

```ts
function minStickers(stickers: string[], target: string): number {
const n = target.length;
const q: number[] = [0];
const vis: boolean[] = Array(1 << n).fill(false);
vis[0] = true;
for (let ans = 0; q.length; ++ans) {
const qq: number[] = [];
for (const cur of q) {
if (cur === (1 << n) - 1) {
return ans;
}
for (const s of stickers) {
const cnt: number[] = Array(26).fill(0);
for (const c of s) {
cnt[c.charCodeAt(0) - 97]++;
}
let nxt = cur;
for (let i = 0; i < n; ++i) {
const j = target.charCodeAt(i) - 97;
if (((cur >> i) & 1) === 0 && cnt[j]) {
nxt |= 1 << i;
cnt[j]--;
}
}
if (!vis[nxt]) {
vis[nxt] = true;
qq.push(nxt);
}
}
}
q.splice(0, q.length, ...qq);
}
return -1;
}
```

#### Rust

```rust
Expand Down
Loading
Loading