[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
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
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 word1
to 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_2
, word_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 <= words.length <= 1000
1 <= words[i].length <= 16
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 <= words.length <= 1000
1 <= words[i].length <= 16
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 }
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 }