题目描述:
现在,我们用一些方块来堆砌一个金字塔。 每个方块用仅包含一个字母的字符串表示,例如 “Z”。
使用三元组表示金字塔的堆砌规则如下:
(A, B, C) 表示,“C”为顶层方块,方块“A”、“B”分别作为方块“C”下一层的的左、右子块。当且仅当(A, B, C)是被允许的三元组,我们才可以将其堆砌上。
初始时,给定金字塔的基层
bottom
,用一个字符串表示。一个允许的三元组列表allowed
,每个三元组用一个长度为 3 的字符串表示。如果可以由基层一直堆到塔尖返回true,否则返回false。
示例:
输入: bottom = "XYZ", allowed = ["XYD", "YZE", "DEA", "FFF"] 输出: true 解析: 可以堆砌成这样的金字塔: A / \ D E / \ / \ X Y Z 因为符合('X', 'Y', 'D'), ('Y', 'Z', 'E') 和 ('D', 'E', 'A') 三种规则。
深度遍历
思路:
首先要判断bottom
是否可以垒到上一层,如果不能直接返回False
,可以垒到上一层就是说,我们找出所有可以由这一层垒到上一层的字符串.依次递归下去,如果可以垒字符串长度只要1
,说明这个金字塔是可以堆出来的.
最重要问题是,如何找到下一层所有可能组成的字符串?
两个工具:
- 字典
- 深度遍历
字典记录由前两个字母组成的所有字符串.
代码:
class Solution(object):
def pyramidTransition(self, bottom, allowed):
"""
:type bottom: str
:type allowed: List[str]
:rtype: bool
"""
lookup = {}
# 用前两个字母最为键,找出所有由前两个字母的字符串
for item in allowed:
if item[:2] not in lookup:
lookup[item[:2]] = [item[2]]
else:
lookup[item[:2]].append(item[2])
# 判读这一层是否可以垒到上一层
def helper(bottom):
n = len(bottom)
if n == 1:
return True
for i in range(n - 1):
if bottom[i:i + 2] not in lookup:
return False
# 找下一层字符串
next_strs = []
getList(bottom, 0, n, "", next_strs)
for next_str in next_strs:
if helper(next_str):
return True
return False
# 找下一层的所有字符串的可能
def getList(bottom, idx, n, temp, next_strs):
if idx == n - 1:
next_strs.append(temp)
return
for com_str in lookup[bottom[idx:idx + 2]]:
getList(bottom, idx + 1, n, temp + com_str, next_strs)
return helper(bottom)
测试:
a = Solution()
print(a.pyramidTransition(bottom = "XYZ", allowed = ["XYD", "YZE", "DEA", "FFF"]))
print(a.pyramidTransition(bottom = "XXYX", allowed = ["XXX", "XXY", "XYX", "XYY", "YXZ"]))
结果:
True
False
完全正确!
AC! 舒服