Skip to content

Commit a7a2357

Browse files
committedSep 29, 2022
feat: add solutions to lc problem: No.0756
No.0756.Pyramid Transition Matrix
1 parent a909538 commit a7a2357

File tree

6 files changed

+431
-2
lines changed

6 files changed

+431
-2
lines changed
 

‎solution/0700-0799/0756.Pyramid Transition Matrix/README.md

+152-1
Original file line numberDiff line numberDiff line change
@@ -59,22 +59,173 @@
5959

6060
<!-- 这里可写通用的实现逻辑 -->
6161

62+
**方法一:记忆化搜索**
63+
64+
定义哈希表 $d$ 存放允许的三角形图案,其中键为两个字符,值为对应的字符列表,表示两个字符可以组成一个三角形图案,三角形图案的顶部为值列表的每一项。
65+
66+
从最底层开始,对于每一层的每两个相邻的字符,如果它们可以组成一个三角形图案,那么就将三角形图案的顶部字符加入到下一层的对应位置的字符列表中,然后对下一层进行递归处理。
67+
68+
时间复杂度 $O(C^N)$。其中 $C$ 是字符集的大小,而 $N$ 是 `bottom` 字符串的长度。
69+
6270
<!-- tabs:start -->
6371

6472
### **Python3**
6573

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

6876
```python
69-
77+
class Solution:
78+
def pyramidTransition(self, bottom: str, allowed: List[str]) -> bool:
79+
@cache
80+
def dfs(s):
81+
if len(s) == 1:
82+
return True
83+
t = []
84+
for a, b in pairwise(s):
85+
cs = d[a, b]
86+
if not cs:
87+
return False
88+
t.append(cs)
89+
return any(dfs(''.join(nxt)) for nxt in product(*t))
90+
91+
d = defaultdict(list)
92+
for a, b, c in allowed:
93+
d[a, b].append(c)
94+
return dfs(bottom)
7095
```
7196

7297
### **Java**
7398

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

76101
```java
102+
class Solution {
103+
private int[][] f = new int[7][7];
104+
private Map<String, Boolean> dp = new HashMap<>();
105+
106+
public boolean pyramidTransition(String bottom, List<String> allowed) {
107+
for (String s : allowed) {
108+
int a = s.charAt(0) - 'A', b = s.charAt(1) - 'A';
109+
f[a][b] |= 1 << (s.charAt(2) - 'A');
110+
}
111+
return dfs(bottom, new StringBuilder());
112+
}
113+
114+
boolean dfs(String s, StringBuilder t) {
115+
if (s.length() == 1) {
116+
return true;
117+
}
118+
if (t.length() + 1 == s.length()) {
119+
return dfs(t.toString(), new StringBuilder());
120+
}
121+
String k = s + "." + t.toString();
122+
if (dp.containsKey(k)) {
123+
return dp.get(k);
124+
}
125+
int a = s.charAt(t.length()) - 'A', b = s.charAt(t.length() + 1) - 'A';
126+
int cs = f[a][b];
127+
for (int i = 0; i < 7; ++i) {
128+
if (((cs >> i) & 1) == 1) {
129+
t.append((char) ('A' + i));
130+
if (dfs(s, t)) {
131+
dp.put(k, true);
132+
return true;
133+
}
134+
t.deleteCharAt(t.length() - 1);
135+
}
136+
}
137+
dp.put(k, false);
138+
return false;
139+
}
140+
}
141+
```
142+
143+
### **C++**
144+
145+
```cpp
146+
class Solution {
147+
public:
148+
int f[7][7];
149+
unordered_map<string, bool> dp;
150+
151+
bool pyramidTransition(string bottom, vector<string>& allowed) {
152+
memset(f, 0, sizeof f);
153+
for (auto& s : allowed) {
154+
int a = s[0] - 'A', b = s[1] - 'A';
155+
f[a][b] |= 1 << (s[2] - 'A');
156+
}
157+
return dfs(bottom, "");
158+
}
159+
160+
bool dfs(string& s, string t) {
161+
if (s.size() == 1) {
162+
return true;
163+
}
164+
if (t.size() + 1 == s.size()) {
165+
return dfs(t, "");
166+
}
167+
string k = s + "." + t;
168+
if (dp.count(k)) {
169+
return dp[k];
170+
}
171+
int a = s[t.size()] - 'A', b = s[t.size() + 1] - 'A';
172+
int cs = f[a][b];
173+
for (int i = 0; i < 7; ++i) {
174+
if ((cs >> i) & 1) {
175+
if (dfs(s, t + (char) (i + 'A'))) {
176+
dp[k] = true;
177+
return true;
178+
}
179+
}
180+
}
181+
dp[k] = false;
182+
return false;
183+
}
184+
};
185+
```
77186
187+
### **Go**
188+
189+
```go
190+
func pyramidTransition(bottom string, allowed []string) bool {
191+
f := make([][]int, 7)
192+
for i := range f {
193+
f[i] = make([]int, 7)
194+
}
195+
for _, s := range allowed {
196+
a, b := s[0]-'A', s[1]-'A'
197+
f[a][b] |= 1 << (s[2] - 'A')
198+
}
199+
dp := map[string]bool{}
200+
var dfs func(s string, t []byte) bool
201+
dfs = func(s string, t []byte) bool {
202+
if len(s) == 1 {
203+
return true
204+
}
205+
if len(t)+1 == len(s) {
206+
return dfs(string(t), []byte{})
207+
}
208+
k := s + "." + string(t)
209+
if v, ok := dp[k]; ok {
210+
return v
211+
}
212+
a, b := s[len(t)]-'A', s[len(t)+1]-'A'
213+
cs := f[a][b]
214+
for i := 0; i < 7; i++ {
215+
if ((cs >> i) & 1) == 1 {
216+
t = append(t, byte('A'+i))
217+
if dfs(s, t) {
218+
dp[k] = true
219+
return true
220+
}
221+
t = t[:len(t)-1]
222+
}
223+
}
224+
dp[k] = false
225+
return false
226+
}
227+
return dfs(bottom, []byte{})
228+
}
78229
```
79230

80231
### **...**

‎solution/0700-0799/0756.Pyramid Transition Matrix/README_EN.md

+144-1
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,156 @@ Starting from the bottom (level 4), there are multiple ways to build level 3, bu
5454
### **Python3**
5555

5656
```python
57-
57+
class Solution:
58+
def pyramidTransition(self, bottom: str, allowed: List[str]) -> bool:
59+
@cache
60+
def dfs(s):
61+
if len(s) == 1:
62+
return True
63+
t = []
64+
for a, b in pairwise(s):
65+
cs = d[a, b]
66+
if not cs:
67+
return False
68+
t.append(cs)
69+
return any(dfs(''.join(nxt)) for nxt in product(*t))
70+
71+
d = defaultdict(list)
72+
for a, b, c in allowed:
73+
d[a, b].append(c)
74+
return dfs(bottom)
5875
```
5976

6077
### **Java**
6178

6279
```java
80+
class Solution {
81+
private int[][] f = new int[7][7];
82+
private Map<String, Boolean> dp = new HashMap<>();
83+
84+
public boolean pyramidTransition(String bottom, List<String> allowed) {
85+
for (String s : allowed) {
86+
int a = s.charAt(0) - 'A', b = s.charAt(1) - 'A';
87+
f[a][b] |= 1 << (s.charAt(2) - 'A');
88+
}
89+
return dfs(bottom, new StringBuilder());
90+
}
91+
92+
boolean dfs(String s, StringBuilder t) {
93+
if (s.length() == 1) {
94+
return true;
95+
}
96+
if (t.length() + 1 == s.length()) {
97+
return dfs(t.toString(), new StringBuilder());
98+
}
99+
String k = s + "." + t.toString();
100+
if (dp.containsKey(k)) {
101+
return dp.get(k);
102+
}
103+
int a = s.charAt(t.length()) - 'A', b = s.charAt(t.length() + 1) - 'A';
104+
int cs = f[a][b];
105+
for (int i = 0; i < 7; ++i) {
106+
if (((cs >> i) & 1) == 1) {
107+
t.append((char) ('A' + i));
108+
if (dfs(s, t)) {
109+
dp.put(k, true);
110+
return true;
111+
}
112+
t.deleteCharAt(t.length() - 1);
113+
}
114+
}
115+
dp.put(k, false);
116+
return false;
117+
}
118+
}
119+
```
120+
121+
### **C++**
122+
123+
```cpp
124+
class Solution {
125+
public:
126+
int f[7][7];
127+
unordered_map<string, bool> dp;
128+
129+
bool pyramidTransition(string bottom, vector<string>& allowed) {
130+
memset(f, 0, sizeof f);
131+
for (auto& s : allowed) {
132+
int a = s[0] - 'A', b = s[1] - 'A';
133+
f[a][b] |= 1 << (s[2] - 'A');
134+
}
135+
return dfs(bottom, "");
136+
}
137+
138+
bool dfs(string& s, string t) {
139+
if (s.size() == 1) {
140+
return true;
141+
}
142+
if (t.size() + 1 == s.size()) {
143+
return dfs(t, "");
144+
}
145+
string k = s + "." + t;
146+
if (dp.count(k)) {
147+
return dp[k];
148+
}
149+
int a = s[t.size()] - 'A', b = s[t.size() + 1] - 'A';
150+
int cs = f[a][b];
151+
for (int i = 0; i < 7; ++i) {
152+
if ((cs >> i) & 1) {
153+
if (dfs(s, t + (char) (i + 'A'))) {
154+
dp[k] = true;
155+
return true;
156+
}
157+
}
158+
}
159+
dp[k] = false;
160+
return false;
161+
}
162+
};
163+
```
63164
165+
### **Go**
166+
167+
```go
168+
func pyramidTransition(bottom string, allowed []string) bool {
169+
f := make([][]int, 7)
170+
for i := range f {
171+
f[i] = make([]int, 7)
172+
}
173+
for _, s := range allowed {
174+
a, b := s[0]-'A', s[1]-'A'
175+
f[a][b] |= 1 << (s[2] - 'A')
176+
}
177+
dp := map[string]bool{}
178+
var dfs func(s string, t []byte) bool
179+
dfs = func(s string, t []byte) bool {
180+
if len(s) == 1 {
181+
return true
182+
}
183+
if len(t)+1 == len(s) {
184+
return dfs(string(t), []byte{})
185+
}
186+
k := s + "." + string(t)
187+
if v, ok := dp[k]; ok {
188+
return v
189+
}
190+
a, b := s[len(t)]-'A', s[len(t)+1]-'A'
191+
cs := f[a][b]
192+
for i := 0; i < 7; i++ {
193+
if ((cs >> i) & 1) == 1 {
194+
t = append(t, byte('A'+i))
195+
if dfs(s, t) {
196+
dp[k] = true
197+
return true
198+
}
199+
t = t[:len(t)-1]
200+
}
201+
}
202+
dp[k] = false
203+
return false
204+
}
205+
return dfs(bottom, []byte{})
206+
}
64207
```
65208

66209
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
class Solution {
2+
public:
3+
int f[7][7];
4+
unordered_map<string, bool> dp;
5+
6+
bool pyramidTransition(string bottom, vector<string>& allowed) {
7+
memset(f, 0, sizeof f);
8+
for (auto& s : allowed) {
9+
int a = s[0] - 'A', b = s[1] - 'A';
10+
f[a][b] |= 1 << (s[2] - 'A');
11+
}
12+
return dfs(bottom, "");
13+
}
14+
15+
bool dfs(string& s, string t) {
16+
if (s.size() == 1) {
17+
return true;
18+
}
19+
if (t.size() + 1 == s.size()) {
20+
return dfs(t, "");
21+
}
22+
string k = s + "." + t;
23+
if (dp.count(k)) {
24+
return dp[k];
25+
}
26+
int a = s[t.size()] - 'A', b = s[t.size() + 1] - 'A';
27+
int cs = f[a][b];
28+
for (int i = 0; i < 7; ++i) {
29+
if ((cs >> i) & 1) {
30+
if (dfs(s, t + (char) (i + 'A'))) {
31+
dp[k] = true;
32+
return true;
33+
}
34+
}
35+
}
36+
dp[k] = false;
37+
return false;
38+
}
39+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
func pyramidTransition(bottom string, allowed []string) bool {
2+
f := make([][]int, 7)
3+
for i := range f {
4+
f[i] = make([]int, 7)
5+
}
6+
for _, s := range allowed {
7+
a, b := s[0]-'A', s[1]-'A'
8+
f[a][b] |= 1 << (s[2] - 'A')
9+
}
10+
dp := map[string]bool{}
11+
var dfs func(s string, t []byte) bool
12+
dfs = func(s string, t []byte) bool {
13+
if len(s) == 1 {
14+
return true
15+
}
16+
if len(t)+1 == len(s) {
17+
return dfs(string(t), []byte{})
18+
}
19+
k := s + "." + string(t)
20+
if v, ok := dp[k]; ok {
21+
return v
22+
}
23+
a, b := s[len(t)]-'A', s[len(t)+1]-'A'
24+
cs := f[a][b]
25+
for i := 0; i < 7; i++ {
26+
if ((cs >> i) & 1) == 1 {
27+
t = append(t, byte('A'+i))
28+
if dfs(s, t) {
29+
dp[k] = true
30+
return true
31+
}
32+
t = t[:len(t)-1]
33+
}
34+
}
35+
dp[k] = false
36+
return false
37+
}
38+
return dfs(bottom, []byte{})
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
class Solution {
2+
private int[][] f = new int[7][7];
3+
private Map<String, Boolean> dp = new HashMap<>();
4+
5+
public boolean pyramidTransition(String bottom, List<String> allowed) {
6+
for (String s : allowed) {
7+
int a = s.charAt(0) - 'A', b = s.charAt(1) - 'A';
8+
f[a][b] |= 1 << (s.charAt(2) - 'A');
9+
}
10+
return dfs(bottom, new StringBuilder());
11+
}
12+
13+
boolean dfs(String s, StringBuilder t) {
14+
if (s.length() == 1) {
15+
return true;
16+
}
17+
if (t.length() + 1 == s.length()) {
18+
return dfs(t.toString(), new StringBuilder());
19+
}
20+
String k = s + "." + t.toString();
21+
if (dp.containsKey(k)) {
22+
return dp.get(k);
23+
}
24+
int a = s.charAt(t.length()) - 'A', b = s.charAt(t.length() + 1) - 'A';
25+
int cs = f[a][b];
26+
for (int i = 0; i < 7; ++i) {
27+
if (((cs >> i) & 1) == 1) {
28+
t.append((char) ('A' + i));
29+
if (dfs(s, t)) {
30+
dp.put(k, true);
31+
return true;
32+
}
33+
t.deleteCharAt(t.length() - 1);
34+
}
35+
}
36+
dp.put(k, false);
37+
return false;
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class Solution:
2+
def pyramidTransition(self, bottom: str, allowed: List[str]) -> bool:
3+
@cache
4+
def dfs(s):
5+
if len(s) == 1:
6+
return True
7+
t = []
8+
for a, b in pairwise(s):
9+
cs = d[a, b]
10+
if not cs:
11+
return False
12+
t.append(cs)
13+
return any(dfs(''.join(nxt)) for nxt in product(*t))
14+
15+
d = defaultdict(list)
16+
for a, b, c in allowed:
17+
d[a, b].append(c)
18+
return dfs(bottom)

0 commit comments

Comments
 (0)
Please sign in to comment.