• [Swift]LeetCode943. 最短超级串 | Find the Shortest Superstring


    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:山青咏芝(shanqingyongzhi)
    ➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址:https://www.cnblogs.com/strengthen/p/10015724.html 
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    Given an array A of strings, find any smallest string that contains each string in A as a substring.

    We may assume that no string in A is substring of another string in A.

    Example 1:

    Input: ["alex","loves","leetcode"]
    Output: "alexlovesleetcode"
    Explanation: All permutations of "alex","loves","leetcode" would also be accepted.
    

    Example 2:

    Input: ["catg","ctaagt","gcta","ttca","atgcatc"]
    Output: "gctaagttcatgcatc"

    Note:

    1. 1 <= A.length <= 12
    2. 1 <= A[i].length <= 20

    给定一个字符串数组 A,找到以 A 中每个字符串作为子字符串的最短字符串。

    我们可以假设 A 中没有字符串是 A 中另一个字符串的子字符串。

    示例 1:

    输入:["alex","loves","leetcode"]
    输出:"alexlovesleetcode"
    解释:"alex","loves","leetcode" 的所有排列都会被接受。

    示例 2:

    输入:["catg","ctaagt","gcta","ttca","atgcatc"]
    输出:"gctaagttcatgcatc"

    提示:

    1. 1 <= A.length <= 12
    2. 1 <= A[i].length <= 20

     100ms

     1 class Solution {
     2     func countSubstr(_ A: [String], _ n: String) -> Int {
     3       var sum = 0
     4       for var s in A {
     5         if n.contains(s) {
     6           sum += s.count
     7         }
     8       }
     9       return sum
    10     }
    11     func shortestSuperstring(_ Ain: [String]) -> String {
    12         var A = Ain
    13         while A.count > 1 {
    14           var maxC = 0
    15           var newStr = ""
    16           for var i in 0..<A.count {
    17             for var j in 0..<A.count {
    18               guard i != j else {
    19                 continue
    20               } 
    21               if A[i].count == 1 { continue }
    22               for var l in 1...A[i].count-1 {
    23                 if A[j].hasPrefix(A[i].suffix(l)) {
    24                   let n = A[i] + A[j].suffix(A[j].count - l)
    25                   let C = countSubstr(A, n) - n.count
    26                   if C > maxC {
    27                     maxC = C
    28                     newStr = n
    29                   }
    30                 }
    31               }
    32             }
    33           }
    34           if maxC == 0 {
    35             newStr = A[0] + A[1]
    36           }
    37           A.removeAll(where: { newStr.contains($0) })
    38           A.append(newStr)
    39         }
    40         return A[0]
    41     }
    42 }
    43 
    44 extension String { 
    45    func contains(_ find: String) -> Bool{
    46      return self.range(of: find) != nil
    47    }
    48 }

    364ms

      1 class Solution {
      2     func shortestSuperstring(_ A: [String]) -> String {
      3         var N:Int = A.count
      4         
      5         // Populate overlaps
      6         var overlaps:[[Int]] = [[Int]](repeating:[Int](repeating:0,count:N),count:N)
      7         for i in 0..<N
      8         {
      9             for j in 0..<N
     10             {
     11                 if i != j
     12                 {
     13                     var m:Int = min(A[i].count, A[j].count)
     14                     for k in (0...m).reversed()
     15                     {
     16                         if A[i].hasSuffix(A[j].substring(0, k))
     17                         {
     18                             overlaps[i][j] = k
     19                             break
     20                         }
     21                     }
     22                 }
     23             }
     24         }
     25         // dp[mask][i] = most overlap with mask, ending with ith element
     26         var dp:[[Int]] = [[Int]](repeating:[Int](repeating:0,count:N),count:1<<N)
     27         var parent:[[Int]] = [[Int]](repeating:[Int](repeating:-1,count:N),count:1<<N)
     28         for mask in 0..<(1<<N)
     29         {
     30             for bit in 0..<N
     31             {
     32                 if ((mask >> bit) & 1) > 0
     33                 {
     34                     // Let's try to find dp[mask][bit].  Previously, we had
     35                     // a collection of items represented by pmask.
     36                     var pmask:Int = mask ^ (1 << bit)
     37                     if pmask == 0 {continue}
     38                     for i in 0..<N
     39                     {
     40                         if ((pmask >> i) & 1) > 0
     41                         {
     42                             // For each bit i in pmask, calculate the value
     43                             // if we ended with word i, then added word 'bit'.
     44                             var val:Int = dp[pmask][i] + overlaps[i][bit]
     45                             if val > dp[mask][bit]
     46                             {
     47                                 dp[mask][bit] = val
     48                                 parent[mask][bit] = i
     49                             }
     50                         }
     51                     }  
     52                 }
     53             }
     54         }
     55         // # Answer will have length sum(len(A[i]) for i) - max(dp[-1])
     56         // Reconstruct answer, first as a sequence 'perm' representing
     57         // the indices of each word from left to right.
     58         var perm:[Int] = [Int](repeating:0,count:N)
     59         var seen:[Bool] = [Bool](repeating:false,count:N)
     60         var t:Int = 0
     61         var mask:Int = (1 << N) - 1
     62         
     63         // p: the last element of perm (last word written left to right)
     64         var p:Int = 0
     65         for j in 0..<N
     66         {
     67             if dp[(1<<N) - 1][j] > dp[(1<<N) - 1][p]
     68             {
     69                 p = j
     70             }
     71         }
     72         
     73         // Follow parents down backwards path that retains maximum overlap
     74         while (p != -1)
     75         {
     76             perm[t] = p
     77             t += 1
     78             seen[p] = true
     79             var p2:Int = parent[mask][p]
     80             mask ^= 1 << p
     81             p = p2
     82         }        
     83         
     84         // Reverse perm
     85         for i in 0..<(t/2)
     86         {
     87             var v:Int = perm[i]
     88             perm[i] = perm[t-1-i]
     89             perm[t-1-i] = v
     90         }
     91         
     92         // Fill in remaining words not yet added
     93         for i in 0..<N
     94         {
     95             if !seen[i]
     96             {
     97                 perm[t] = i
     98                 t += 1
     99             }
    100         }
    101         
    102         // Reconstruct final answer given perm
    103         var ans:String = String(A[perm[0]])
    104         for i in 1..<N
    105         {
    106             var overlap:Int = overlaps[perm[i-1]][perm[i]]
    107             ans.append(A[perm[i]].substring(overlap))
    108         }
    109         return ans
    110     }
    111 }
    112 
    113 extension String {    
    114 // 截取字符串:从index到结束处
    115     // - Parameter index: 开始索引
    116     // - Returns: 子字符串
    117     func substring(_ index: Int) -> String {
    118         let theIndex = self.index(self.endIndex, offsetBy: index - self.count)
    119         return String(self[theIndex..<endIndex])
    120     }
    121     
    122     // 截取字符串:指定索引和字符数
    123     // - begin: 开始截取处索引
    124     // - count: 截取的字符数量
    125     func substring(_ begin:Int,_ count:Int) -> String {
    126         let start = self.index(self.startIndex, offsetBy: max(0, begin))
    127         let end = self.index(self.startIndex, offsetBy:  min(self.count, begin + count))
    128         return String(self[start..<end]) 
    129     }
    130 }
  • 相关阅读:
    asp.net实现页面的一般处理程序(CGI)学习笔记
    .NET下的状态(State)模式 行为型模式
    (插件Plugin)AssemblyLoader解决方案(插件开发)
    SQL基础编写基本的SQL SELECT 语句
    在查询语句中使用NOLOCK和READPAST(ZT)
    C# 3.0语言增强学习笔记(一)
    ram,rom,flash
    自动激活你的ActiveX控件
    用C#编写ActiveX控件(二)
    用C#编写ActiveX控件(一)
  • 原文地址:https://www.cnblogs.com/strengthen/p/10015724.html
Copyright © 2020-2023  润新知