Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9e3e2fe

Browse files
committed
feat: add solutions to lc problem: No.1639
No.1639.Number of Ways to Form a Target String Given a Dictionary
1 parent 78ef0fa commit 9e3e2fe

File tree

6 files changed

+400
-2
lines changed

6 files changed

+400
-2
lines changed

‎solution/1600-1699/1639.Number of Ways to Form a Target String Given a Dictionary/README.md‎

Lines changed: 147 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,22 +81,168 @@
8181

8282
<!-- 这里可写通用的实现逻辑 -->
8383

84+
**方法一:预处理 + 记忆化搜索**
85+
86+
我们注意到,字符串数组 $words$ 中的每一个字符串长度都相同,不妨记为 $n,ドル那么我们可以预处理出一个二维数组 $cnt,ドル其中 $cnt[j][c]$ 表示字符串数组 $words$ 中第 $j$ 个位置的字符 $c$ 的数量。
87+
88+
接下来,我们设计一个函数 $dfs(i, j),ドル表示构造 $target[i,..]$ 且当前从 $words$ 中选取的字符位置为 $j$ 的方案数。那么答案就是 $dfs(0, 0)$。
89+
90+
函数 $dfs(i, j)$ 的计算逻辑如下:
91+
92+
- 如果 $i \geq m,ドル说明 $target$ 中的所有字符都已经被选取,那么方案数为 1ドル$。
93+
- 如果 $j \geq n,ドル说明 $words$ 中的所有字符都已经被选取,那么方案数为 0ドル$。
94+
- 否则,我们可以不选择 $words$ 中的第 $j$ 个位置的字符,那么方案数为 $dfs(i, j + 1)$;或者我们选择 $words$ 中的第 $j$ 个位置的字符,那么方案数为 $dfs(i + 1, j + 1) \times cnt[j][target[i] - 'a']$。
95+
96+
最后,我们返回 $dfs(0, 0)$ 即可。注意答案的取模操作。
97+
98+
时间复杂度 $O(m \times n),ドル空间复杂度 $O(m \times n)$。其中 $m$ 为字符串 $target$ 的长度,而 $n$ 为字符串数组 $words$ 中每个字符串的长度。
99+
84100
<!-- tabs:start -->
85101

86102
### **Python3**
87103

88104
<!-- 这里可写当前语言的特殊实现逻辑 -->
89105

90106
```python
91-
107+
class Solution:
108+
def numWays(self, words: List[str], target: str) -> int:
109+
@cache
110+
def dfs(i, j):
111+
if i >= m:
112+
return 1
113+
if j >= n:
114+
return 0
115+
ans = dfs(i, j + 1) + dfs(i + 1, j + 1) * cnt[j][ord(target[i]) - ord("a")]
116+
ans %= mod
117+
return ans
118+
119+
m = len(target)
120+
n = len(words[0])
121+
cnt = [[0] * 26 for _ in range(n)]
122+
for w in words:
123+
for j, c in enumerate(w):
124+
cnt[j][ord(c) - ord("a")] += 1
125+
mod = 10**9 + 7
126+
return dfs(0, 0)
92127
```
93128

94129
### **Java**
95130

96131
<!-- 这里可写当前语言的特殊实现逻辑 -->
97132

98133
```java
134+
class Solution {
135+
private int m;
136+
private int n;
137+
private String target;
138+
private Integer[][] f;
139+
private int[][] cnt;
140+
private final int mod = (int) 1e9 + 7;
141+
142+
public int numWays(String[] words, String target) {
143+
m = target.length();
144+
n = words[0].length();
145+
f = new Integer[m][n];
146+
this.target = target;
147+
cnt = new int[n][26];
148+
for (var w : words) {
149+
for (int j = 0; j < n; ++j) {
150+
cnt[j][w.charAt(j) - 'a']++;
151+
}
152+
}
153+
return dfs(0, 0);
154+
}
155+
156+
private int dfs(int i, int j) {
157+
if (i >= m) {
158+
return 1;
159+
}
160+
if (j >= n) {
161+
return 0;
162+
}
163+
if (f[i][j] != null) {
164+
return f[i][j];
165+
}
166+
long ans = dfs(i, j + 1);
167+
ans += 1L * dfs(i + 1, j + 1) * cnt[j][target.charAt(i) - 'a'];
168+
ans %= mod;
169+
return f[i][j] = (int) ans;
170+
}
171+
}
172+
```
173+
174+
### **C++**
175+
176+
```cpp
177+
class Solution {
178+
public:
179+
int numWays(vector<string>& words, string target) {
180+
const int mod = 1e9 + 7;
181+
int m = target.size(), n = words[0].size();
182+
vector<vector<int>> cnt(n, vector<int>(26));
183+
for (auto& w : words) {
184+
for (int j = 0; j < n; ++j) {
185+
++cnt[j][w[j] - 'a'];
186+
}
187+
}
188+
int f[m][n];
189+
memset(f, -1, sizeof(f));
190+
function<int(int, int)> dfs = [&](int i, int j) -> int {
191+
if (i >= m) {
192+
return 1;
193+
}
194+
if (j >= n) {
195+
return 0;
196+
}
197+
if (f[i][j] != -1) {
198+
return f[i][j];
199+
}
200+
int ans = dfs(i, j + 1);
201+
ans = (ans + 1LL * dfs(i + 1, j + 1) * cnt[j][target[i] - 'a']) % mod;
202+
return f[i][j] = ans;
203+
};
204+
return dfs(0, 0);
205+
}
206+
};
207+
```
99208
209+
### **Go**
210+
211+
```go
212+
func numWays(words []string, target string) int {
213+
m, n := len(target), len(words[0])
214+
f := make([][]int, m)
215+
cnt := make([][26]int, n)
216+
for _, w := range words {
217+
for j, c := range w {
218+
cnt[j][c-'a']++
219+
}
220+
}
221+
for i := range f {
222+
f[i] = make([]int, n)
223+
for j := range f[i] {
224+
f[i][j] = -1
225+
}
226+
}
227+
const mod = 1e9 + 7
228+
var dfs func(i, j int) int
229+
dfs = func(i, j int) int {
230+
if i >= m {
231+
return 1
232+
}
233+
if j >= n {
234+
return 0
235+
}
236+
if f[i][j] != -1 {
237+
return f[i][j]
238+
}
239+
ans := dfs(i, j+1)
240+
ans = (ans + dfs(i+1, j+1)*cnt[j][target[i]-'a']) % mod
241+
f[i][j] = ans
242+
return ans
243+
}
244+
return dfs(0, 0)
245+
}
100246
```
101247

102248
### **...**

‎solution/1600-1699/1639.Number of Ways to Form a Target String Given a Dictionary/README_EN.md‎

Lines changed: 131 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,143 @@
6464
### **Python3**
6565

6666
```python
67-
67+
class Solution:
68+
def numWays(self, words: List[str], target: str) -> int:
69+
@cache
70+
def dfs(i, j):
71+
if i >= m:
72+
return 1
73+
if j >= n:
74+
return 0
75+
ans = dfs(i, j + 1) + dfs(i + 1, j + 1) * cnt[j][ord(target[i]) - ord("a")]
76+
ans %= mod
77+
return ans
78+
79+
m = len(target)
80+
n = len(words[0])
81+
cnt = [[0] * 26 for _ in range(n)]
82+
for w in words:
83+
for j, c in enumerate(w):
84+
cnt[j][ord(c) - ord("a")] += 1
85+
mod = 10**9 + 7
86+
return dfs(0, 0)
6887
```
6988

7089
### **Java**
7190

7291
```java
92+
class Solution {
93+
private int m;
94+
private int n;
95+
private String target;
96+
private Integer[][] f;
97+
private int[][] cnt;
98+
private final int mod = (int) 1e9 + 7;
99+
100+
public int numWays(String[] words, String target) {
101+
m = target.length();
102+
n = words[0].length();
103+
f = new Integer[m][n];
104+
this.target = target;
105+
cnt = new int[n][26];
106+
for (var w : words) {
107+
for (int j = 0; j < n; ++j) {
108+
cnt[j][w.charAt(j) - 'a']++;
109+
}
110+
}
111+
return dfs(0, 0);
112+
}
113+
114+
private int dfs(int i, int j) {
115+
if (i >= m) {
116+
return 1;
117+
}
118+
if (j >= n) {
119+
return 0;
120+
}
121+
if (f[i][j] != null) {
122+
return f[i][j];
123+
}
124+
long ans = dfs(i, j + 1);
125+
ans += 1L * dfs(i + 1, j + 1) * cnt[j][target.charAt(i) - 'a'];
126+
ans %= mod;
127+
return f[i][j] = (int) ans;
128+
}
129+
}
130+
```
131+
132+
### **C++**
133+
134+
```cpp
135+
class Solution {
136+
public:
137+
int numWays(vector<string>& words, string target) {
138+
const int mod = 1e9 + 7;
139+
int m = target.size(), n = words[0].size();
140+
vector<vector<int>> cnt(n, vector<int>(26));
141+
for (auto& w : words) {
142+
for (int j = 0; j < n; ++j) {
143+
++cnt[j][w[j] - 'a'];
144+
}
145+
}
146+
int f[m][n];
147+
memset(f, -1, sizeof(f));
148+
function<int(int, int)> dfs = [&](int i, int j) -> int {
149+
if (i >= m) {
150+
return 1;
151+
}
152+
if (j >= n) {
153+
return 0;
154+
}
155+
if (f[i][j] != -1) {
156+
return f[i][j];
157+
}
158+
int ans = dfs(i, j + 1);
159+
ans = (ans + 1LL * dfs(i + 1, j + 1) * cnt[j][target[i] - 'a']) % mod;
160+
return f[i][j] = ans;
161+
};
162+
return dfs(0, 0);
163+
}
164+
};
165+
```
73166
167+
### **Go**
168+
169+
```go
170+
func numWays(words []string, target string) int {
171+
m, n := len(target), len(words[0])
172+
f := make([][]int, m)
173+
cnt := make([][26]int, n)
174+
for _, w := range words {
175+
for j, c := range w {
176+
cnt[j][c-'a']++
177+
}
178+
}
179+
for i := range f {
180+
f[i] = make([]int, n)
181+
for j := range f[i] {
182+
f[i][j] = -1
183+
}
184+
}
185+
const mod = 1e9 + 7
186+
var dfs func(i, j int) int
187+
dfs = func(i, j int) int {
188+
if i >= m {
189+
return 1
190+
}
191+
if j >= n {
192+
return 0
193+
}
194+
if f[i][j] != -1 {
195+
return f[i][j]
196+
}
197+
ans := dfs(i, j+1)
198+
ans = (ans + dfs(i+1, j+1)*cnt[j][target[i]-'a']) % mod
199+
f[i][j] = ans
200+
return ans
201+
}
202+
return dfs(0, 0)
203+
}
74204
```
75205

76206
### **...**
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
class Solution {
2+
public:
3+
int numWays(vector<string>& words, string target) {
4+
const int mod = 1e9 + 7;
5+
int m = target.size(), n = words[0].size();
6+
vector<vector<int>> cnt(n, vector<int>(26));
7+
for (auto& w : words) {
8+
for (int j = 0; j < n; ++j) {
9+
++cnt[j][w[j] - 'a'];
10+
}
11+
}
12+
int f[m][n];
13+
memset(f, -1, sizeof(f));
14+
function<int(int, int)> dfs = [&](int i, int j) -> int {
15+
if (i >= m) {
16+
return 1;
17+
}
18+
if (j >= n) {
19+
return 0;
20+
}
21+
if (f[i][j] != -1) {
22+
return f[i][j];
23+
}
24+
int ans = dfs(i, j + 1);
25+
ans = (ans + 1LL * dfs(i + 1, j + 1) * cnt[j][target[i] - 'a']) % mod;
26+
return f[i][j] = ans;
27+
};
28+
return dfs(0, 0);
29+
}
30+
};
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
func numWays(words []string, target string) int {
2+
m, n := len(target), len(words[0])
3+
f := make([][]int, m)
4+
cnt := make([][26]int, n)
5+
for _, w := range words {
6+
for j, c := range w {
7+
cnt[j][c-'a']++
8+
}
9+
}
10+
for i := range f {
11+
f[i] = make([]int, n)
12+
for j := range f[i] {
13+
f[i][j] = -1
14+
}
15+
}
16+
const mod = 1e9 + 7
17+
var dfs func(i, j int) int
18+
dfs = func(i, j int) int {
19+
if i >= m {
20+
return 1
21+
}
22+
if j >= n {
23+
return 0
24+
}
25+
if f[i][j] != -1 {
26+
return f[i][j]
27+
}
28+
ans := dfs(i, j+1)
29+
ans = (ans + dfs(i+1, j+1)*cnt[j][target[i]-'a']) % mod
30+
f[i][j] = ans
31+
return ans
32+
}
33+
return dfs(0, 0)
34+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /