[Swift]LeetCode756. 金字塔转换矩阵 | Pyramid Transition Matrix
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址: https://www.cnblogs.com/strengthen/p/10532649.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
We are stacking blocks to form a pyramid. Each block has a color which is a one letter string, like `'Z'`.
For every block of color `C` we place not in the bottom row, we are placing it on top of a left block of color `A` and right block of color `B`. We are allowed to place the block there only if `(A, B, C)` is an allowed triple.
We start with a bottom row of bottom
, represented as a single string. We also start with a list of allowed triples allowed
. Each allowed triple is represented as a string of length 3.
Return true if we can build the pyramid all the way to the top, otherwise false.
Example 1:
Input: bottom = "XYZ", allowed = ["XYD", "YZE", "DEA", "FFF"] Output: true Explanation: We can stack the pyramid like this: A / \ D E / \ / \ X Y Z This works because ('X', 'Y', 'D'), ('Y', 'Z', 'E'), and ('D', 'E', 'A') are allowed triples.
Example 2:
Input: bottom = "XXYX", allowed = ["XXX", "XXY", "XYX", "XYY", "YXZ"] Output: false Explanation: We can't stack the pyramid to the top. Note that there could be allowed triples (A, B, C) and (A, B, D) with C != D.
Note:
bottom
will be a string with length in range[2, 8]
.allowed
will have length in range[0, 200]
.- Letters in all strings will be chosen from the set
{'A', 'B', 'C', 'D', 'E', 'F', 'G'}
.
现在,我们用一些方块来堆砌一个金字塔。 每个方块用仅包含一个字母的字符串表示,例如 “Z”。
使用三元组表示金字塔的堆砌规则如下:
(A, B, C) 表示,“C”为顶层方块,方块“A”、“B”分别作为方块“C”下一层的的左、右子块。当且仅当(A, B, C)是被允许的三元组,我们才可以将其堆砌上。
初始时,给定金字塔的基层 bottom
,用一个字符串表示。一个允许的三元组列表 allowed
,每个三元组用一个长度为 3 的字符串表示。
如果可以由基层一直堆到塔尖返回true,否则返回false。
示例 1:
输入: bottom = "XYZ", allowed = ["XYD", "YZE", "DEA", "FFF"] 输出: true 解析: 可以堆砌成这样的金字塔: A / \ D E / \ / \ X Y Z 因为符合('X', 'Y', 'D'), ('Y', 'Z', 'E') 和 ('D', 'E', 'A') 三种规则。
示例 2:
输入: bottom = "XXYX", allowed = ["XXX", "XXY", "XYX", "XYY", "YXZ"] 输出: false 解析: 无法一直堆到塔尖。 注意, 允许存在三元组(A, B, C)和 (A, B, D) ,其中 C != D.
注意:
bottom
的长度范围在[2, 8]
。allowed
的长度范围在[0, 200]
。- 方块的标记字母范围为
{'A', 'B', 'C', 'D', 'E', 'F', 'G'}
。
24ms
1 class Solution { 2 func pyramidTransition(_ bottom: String, _ allowed: [String]) -> Bool { 3 var patterDict = [String: [String]]() 4 for w in allowed { 5 let key = String(w.prefix(2)) 6 let val = String(w.suffix(1)) 7 if patterDict[key] == nil { 8 patterDict[key] = [String]() 9 } 10 patterDict[key]?.append(val) 11 } 12 13 func buildNext(_ A: String, _ ans: String, _ i: Int) -> Bool { 14 //print("A = \(A), ans = \(ans), A = \(i)") 15 if A.count == 0 { //找到可行解 16 return true 17 } 18 if i + 1 == A.count { //某一排全部摆放完成 19 return buildNext(ans, "", 0) 20 } 21 let w = A.subString(from: i, length: 2) 22 if let dic = patterDict[w] { 23 for x in dic { 24 if buildNext(A, ans + x, i + 1) { 25 return true 26 } 27 } 28 } else { 29 return false 30 } 31 32 return false 33 } 34 35 return buildNext(bottom, "", 0) 36 } 37 } 38 39 extension String { 40 func subString(from: Int, length: Int) -> String { 41 let indexStartOfText = self.index(self.startIndex, offsetBy: from) 42 let indexEndOfText = self.index(self.startIndex, offsetBy: from + length) 43 let substring = self[indexStartOfText..<indexEndOfText] 44 return String(substring) 45 } 46 }
40ms
1 class Solution { 2 func pyramidTransition(_ bottom: String, _ allowed: [String]) -> Bool { 3 var map = [String: [Character]]() 4 for s in allowed { 5 let key = String(s.prefix(2)) 6 var arr = map[key, default: [Character]()] 7 arr.append(s.last!) 8 map[key] = arr 9 } 10 var curr = "" 11 var pre = bottom 12 return DFS(&pre, &curr, 0, map) 13 } 14 15 func DFS(_ prev: inout String, _ curr: inout String, _ idx: Int, _ map: [String: [Character]]) -> Bool { 16 if prev.count == 1 { // the total pyramid has been constructed 17 return true 18 } 19 if idx + 1 == prev.count { // the current layer has been constructed 20 var next = "" 21 return DFS(&curr, &next, 0, map); 22 } 23 else { 24 let chars = Array(prev) 25 let key = String(chars[idx..<idx+2]) 26 if map[key] == nil { // no candidate 27 return false 28 } 29 else { // try each candidate 30 let chars = map[key]! 31 for i in 0..<chars.count { 32 curr.append(chars[i]) 33 if DFS(&prev, &curr, idx+1, map) { return true } 34 curr.popLast() // backtracking 35 } 36 return false 37 } 38 } 39 } 40 }
1 class Solution { 2 let arrChar:[Character] = ["A","B","C","D","E","F","G"] 3 func pyramidTransition(_ bottom: String, _ allowed: [String]) -> Bool { 4 var n:Int = bottom.count 5 var dp:[[[Bool]]] = [[[Bool]]](repeating:[[Bool]](repeating:[Bool](repeating:false,count:7),count:n),count:n) 6 var m:[Character:Set<String>] = [Character:Set<String>]() 7 for str in allowed 8 { 9 m[str[2],default:Set<String>()].insert(str.subString(0, 2)) 10 } 11 for i in 0..<n 12 { 13 dp[n - 1][i][bottom[i].ascii - 65] = true 14 } 15 for i in stride(from:n - 2,through:0,by:-1) 16 { 17 for j in 0...i 18 { 19 for ch in arrChar 20 { 21 if m[ch] == nil {continue} 22 for str in m[ch]! 23 { 24 if dp[i + 1][j][str[0].ascii - 65] && dp[i + 1][j + 1][str[1].ascii - 65] 25 { 26 dp[i][j][ch.ascii - 65] = true 27 } 28 } 29 } 30 } 31 } 32 for i in 0..<7 33 { 34 if dp[0][0][i] {return true} 35 } 36 return false 37 } 38 } 39 40 extension String { 41 //subscript函数可以检索数组中的值 42 //直接按照索引方式截取指定索引的字符 43 subscript (_ i: Int) -> Character { 44 //读取字符 45 get {return self[index(startIndex, offsetBy: i)]} 46 } 47 48 // 截取字符串:指定索引和字符数 49 // - begin: 开始截取处索引 50 // - count: 截取的字符数量 51 func subString(_ begin:Int,_ count:Int) -> String { 52 let start = self.index(self.startIndex, offsetBy: max(0, begin)) 53 let end = self.index(self.startIndex, offsetBy: min(self.count, begin + count)) 54 return String(self[start..<end]) 55 } 56 57 } 58 59 //Character扩展 60 extension Character 61 { 62 //Character转ASCII整数值(定义小写为整数值) 63 var ascii: Int { 64 get { 65 return Int(self.unicodeScalars.first?.value ?? 0) 66 } 67 } 68 }