• [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:

    1. bottom will be a string with length in range [2, 8].
    2. allowed will have length in range [0, 200].
    3. 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.
    

    注意:

    1. bottom 的长度范围在 [2, 8]
    2. allowed 的长度范围在[0, 200]
    3. 方块的标记字母范围为{'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 }

    Runtime: 44 ms
    Memory Usage: 20 MB
     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 }
  • 相关阅读:
    [重回VB6]简单的QQWeb网游辅助工具开发之旅1、序言,另类的QQ登陆方法
    QQ和360大战我的观点
    不用IE Test ,快速对IE兼容性进行测试
    第八届软件设计大赛完全作品赛前评析与剧透
    屌丝如何分发大文件(大于1G)
    NetDog 酷炫版 0.1测试版发布
    Jquery制作的页码插件
    使用Html5+CSS3摆脱JS做带提示文字的输入框
    在nhibernate中,Load相同ID的实体对象的时候出错的问题!
    fieldset,legend
  • 原文地址:https://www.cnblogs.com/strengthen/p/10532649.html
Copyright © 2020-2023  润新知