为有牺牲多壮志,敢教日月换新天。

[Swift]LeetCode1048.最长字符串链 | Longest String Chain

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

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

Given a list of words, each word consists of English lowercase letters.

Let's say word1 is a predecessor of word2 if and only if we can add exactly one letter anywhere in word1to make it equal to word2.  For example, "abc" is a predecessor of "abac".

A word chain is a sequence of words [word_1, word_2, ..., word_k] with k >= 1, where word_1 is a predecessor of word_2word_2 is a predecessor of word_3, and so on.

Return the longest possible length of a word chain with words chosen from the given list of words.

Example 1:

Input: ["a","b","ba","bca","bda","bdca"]
Output: 4
Explanation: one of the longest word chain is "a","ba","bda","bdca".

Note:

  1. 1 <= words.length <= 1000
  2. 1 <= words[i].length <= 16
  3. words[i] only consists of English lowercase letters.

给出一个单词列表,其中每个单词都由小写英文字母组成。

如果我们可以在 word1 的任何地方添加一个字母使其变成 word2,那么我们认为 word1 是 word2 的前身。例如,"abc" 是 "abac" 的前身。

词链是单词 [word_1, word_2, ..., word_k] 组成的序列,k >= 1,其中 word_1 是 word_2 的前身,word_2 是 word_3 的前身,依此类推。

从给定单词列表 words 中选择单词组成词链,返回词链的最长可能长度。

示例:

输入:["a","b","ba","bca","bda","bdca"]
输出:4
解释:最长单词链之一为 "a","ba","bda","bdca"。

提示:

  1. 1 <= words.length <= 1000
  2. 1 <= words[i].length <= 16
  3. words[i] 仅由小写英文字母组成。

204ms

 1 class Solution {
 2     func longestStrChain(_ words: [String]) -> Int {
 3         var wordsByLength = Array(repeating: [String: Int](), count: 17)
 4         
 5         for word in words {
 6             wordsByLength[word.count][word] = 1
 7         }
 8         
 9         var returnValue = 1
10         
11         for i in 1...16 {
12             let keys = wordsByLength[i].keys
13             for word in keys {
14                 for j in 0..<word.count {
15                     var prevKey = word
16                     let index = prevKey.index(prevKey.startIndex, offsetBy: j)
17                     prevKey.remove(at: index)
18                     if let result = wordsByLength[prevKey.count][prevKey] {
19                         let this = result + 1
20                         wordsByLength[word.count][word] = this
21                         returnValue = max(returnValue, this)
22                     }
23                 }
24             }
25         }
26         
27         return returnValue
28     }
29 }

696ms

 1 class Solution {
 2     var result = 1
 3     func longestStrChain(_ words: [String]) -> Int {
 4         guard words.count > 0 else {
 5             return 0
 6         }
 7         var memo = [String: Int]()
 8         var dict = [Int: [String]]()
 9         for word in words {
10             dict[word.count] = dict[word.count, default:[String]()]
11             dict[word.count]!.append(word)
12             memo[word] = 1
13         }
14         var sortedWords = words.sorted(by: {$0.count < $1.count})
15         
16         for word in sortedWords {
17             for i in 0..<word.count {
18                 var chars = Array(word)
19                 chars.remove(at: i)
20                 let last = String(chars)
21                 if let value = dict[last.count], value.contains(last) {
22                     memo[word] = max(memo[word]!, memo[last]! + 1)
23                     result = max(memo[word]!, result)
24                 }
25             }
26         }
27         return result
28     }
29 }

Runtime: 2092 ms
Memory Usage: 21 MB
 1 class Solution {
 2     func longestStrChain(_ words: [String]) -> Int {
 3         var words = words
 4         words.sort(by:{
 5             return $0.count < $1.count
 6         })
 7         let n:Int = words.count
 8         var dp:[Int] = [Int](repeating:0,count:n)
 9         dp[0] = 1
10         for i in 1..<n
11         {
12             dp[i] = 1
13             for j in 0..<i
14             {
15                 if predecessor(words[j], words[i])
16                 {
17                     dp[i] = max(dp[i], dp[j] + 1)
18                 }
19                 
20             }
21         }
22         return dp.max() ?? 0
23     }
24     
25     func predecessor(_ t:String,_ s:String) -> Bool
26     {
27         let m:Int = t.count
28         let n:Int = s.count
29         if m != n - 1 {return false}
30         var cnt:Int = 0
31         var i:Int = 0
32         var j:Int = 0
33         let arrT:[Character] = Array(t)
34         let arrS:[Character] = Array(s)
35         while(i < m && j < n)
36         {
37             if arrT[i] == arrS[j]
38             {
39                 i += 1
40                 j += 1
41             }
42             else
43             {
44                 if cnt > 0 {return false}
45                 cnt += 1
46                 j += 1
47             }
48         }
49         return true
50     }
51 }

 

 

posted @ 2019-05-18 10:05  为敢技术  阅读(356)  评论(0编辑  收藏  举报