[Swift]LeetCode916.单词子集 | Word Subsets
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/9857027.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
We are given two arrays A
and B
of words. Each word is a string of lowercase letters.
Now, say that word b
is a subset of word a
if every letter in b
occurs in a
, including multiplicity. For example, "wrr"
is a subset of "warrior"
, but is not a subset of "world"
.
Now say a word a
from A
is universal if for every b
in B
, b
is a subset of a
.
Return a list of all universal words in A
. You can return the words in any order.
Example 1:
Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["e","o"]
Output: ["facebook","google","leetcode"]
Example 2:
Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["l","e"]
Output: ["apple","google","leetcode"]
Example 3:
Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["e","oo"]
Output: ["facebook","google"]
Example 4:
Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["lo","eo"]
Output: ["google","leetcode"]
Example 5:
Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["ec","oc","ceo"]
Output: ["facebook","leetcode"]
Note:
1 <= A.length, B.length <= 10000
1 <= A[i].length, B[i].length <= 10
A[i]
andB[i]
consist only of lowercase letters.- All words in
A[i]
are unique: there isn'ti != j
withA[i] == A[j]
.
我们给出了两个数组A
和B
单词。每个单词都是一串小写字母。
现在,假设每个字母都出现在,包括多重性,那么单词b
就是单词的一个子集。例如,"wrr"是"warrior"的子集,但不是"world"的子集。
现在说一个字a
从A
是普遍的,若对所有b
的B
,b
是的一个子集a
。
返回所有通用单词的列表A
。您可以按任何顺序返回单词。
例1:
输入: A = [“amazon”,“apple”,“facebook”,“google”,“leetcode”],B = [“e”,“o”] 输出:[“facebook”,“google”,“leetcode “]
例2:
输入: A = [“amazon”,“apple”,“facebook”,“google”,“leetcode”],B = [“l”,“e”] 输出:[“apple”,“google”,“leetcode “]
例3:
输入: A = [“amazon”,“apple”,“facebook”,“google”,“leetcode”],B = [“e”,“oo”] 输出:[“facebook”,“google”]
例4:
输入: A = [“amazon”,“apple”,“facebook”,“google”,“leetcode”],B = [“lo”,“eo”] 输出:[“google”,“leetcode”]
例5:
输入: A = [“amazon”,“apple”,“facebook”,“google”,“leetcode”],B = [“ec”,“oc”,“ceo”] 输出:[“facebook”,“leetcode “]
注意:
1 <= A.length, B.length <= 10000
1 <= A[i].length, B[i].length <= 10
A[i]
并且B[i]
仅由小写字母组成。- 在所有的话
A[i]
都是独一无二的:没有i != j
用A[i] == A[j]
。
1536ms
1 class Solution { 2 func wordSubsets(_ A: [String], _ B: [String]) -> [String] { 3 var patterns = Dictionary(B[0].map { ($0, 1) }, uniquingKeysWith: +) 4 for b in B { 5 updatePatterns(&patterns, b) 6 } 7 var results = [String]() 8 outer: for a in A { 9 let dict = Dictionary(a.map { ($0, 1) }, uniquingKeysWith: +) 10 for key in patterns.keys { 11 guard let value = dict[key] else { 12 continue outer 13 } 14 if value < patterns[key]! { 15 continue outer 16 } 17 } 18 results.append(a) 19 } 20 return results 21 } 22 23 fileprivate func updatePatterns(_ patterns: inout [Character : Int], _ library: String) { 24 var chars = Array(library) 25 let dict = Dictionary(chars.map { ($0, 1) }, uniquingKeysWith: +) 26 for key in dict.keys { 27 if let pattern = patterns[key] { 28 patterns[key] = max(pattern, dict[key]!) 29 } else { 30 patterns[key] = dict[key] 31 } 32 } 33 } 34 }
1864ms
1 class Solution { 2 func wordSubsets(_ A: [String], _ B: [String]) -> [String] { 3 var bmax:[Int] = [Int](repeating: 0,count: 26) 4 for b in B 5 { 6 var bCount:[Int] = count(b) 7 for i in 0..<26 8 { 9 bmax[i] = max(bmax[i], bCount[i]) 10 } 11 } 12 var ans:[String] = [String]() 13 //类似goto语句功能 14 search: 15 for a in A 16 { 17 var aCount:[Int] = count(a) 18 for i in 0..<26 19 { 20 if aCount[i] < bmax[i] 21 { 22 23 continue search 24 25 } 26 } 27 ans.append(a) 28 } 29 return ans 30 } 31 32 func count(_ str:String) -> [Int] 33 { 34 var ans:[Int] = [Int](repeating: 0,count: 26) 35 for char in str.characters 36 { 37 //A:65 a:97 38 ans[char.toInt() - 97] += 1 39 } 40 return ans 41 } 42 } 43 44 //Character扩展方法 45 extension Character 46 { 47 func toInt() -> Int 48 { 49 var num:Int = Int() 50 for scalar in String(self).unicodeScalars 51 { 52 num = Int(scalar.value) 53 } 54 return num 55 } 56 }
2056ms
1 class Solution { 2 func wordSubsets(_ A: [String], _ B: [String]) -> [String] { 3 var hms: [Character:Int] = [:] 4 for b in B { 5 var locHm: [Character:Int] = [:] 6 for symbol in b { 7 let temp = (locHm[symbol] ?? 0) + 1 8 locHm[symbol] = temp 9 hms[symbol] = max((hms[symbol] ?? 0), temp) 10 } 11 } 12 13 var res: [Int] = [] 14 var aHms: [[Character:Int]] = Array(repeating: [:], count: A.count) 15 for (index, a) in A.enumerated() { 16 for symbol in a { 17 aHms[index][symbol] = (aHms[index][symbol] ?? 0) + 1 18 } 19 } 20 21 for (index, hm) in aHms.enumerated() { 22 var ok = true 23 for k in hms.keys { 24 if (hm[k] ?? 0) < hms[k]! { 25 ok = false 26 break 27 } 28 } 29 if ok { 30 res.append(index) 31 } 32 } 33 34 return res.map({A[$0]}) 35 } 36 }
2208ms
1 class Solution { 2 func wordSubsets(_ A: [String], _ B: [String]) -> [String] { 3 let bDicts:[[Character:Int]] = B.map { wordDict($0) } 4 var bWord: [Character:Int] = [:] 5 for bDict in bDicts { 6 for (ch, count) in bDict { 7 bWord[ch] = max((bWord[ch] ?? 0), count) 8 } 9 } 10 11 var result: [String] = [] 12 for aWord in A { 13 let aDict = wordDict(aWord) 14 if contains(aDict, bWord) { 15 result.append(aWord) 16 } 17 } 18 return result 19 } 20 21 func wordDict(_ str: String) -> [Character:Int] { 22 var result: [Character:Int] = [:] 23 for ch in str { 24 result[ch] = (result[ch] ?? 0) + 1 25 } 26 return result 27 } 28 29 func contains(_ aDict:[Character:Int], _ bDict:[Character: Int]) -> Bool { 30 for (key, count) in bDict { 31 if aDict[key] == nil || aDict[key]! < count { 32 return false 33 } 34 } 35 return true 36 } 37 }
2240ms
1 class Solution { 2 func wordSubsets(_ A: [String], _ B: [String]) -> [String] { 3 let universe: [Character: Int] = B.reduce(into: [:]) { res, next in 4 let c = countCharacters(in: next) 5 for kv in c { 6 res[kv.key] = max(kv.value, res[kv.key] ?? 0) 7 } 8 } 9 return A.filter { self.isWord($0, universalIn: universe) } 10 } 11 12 func isWord(_ word: String, universalIn universe: [Character: Int]) -> Bool { 13 var wordCount = countCharacters(in: word) 14 for kv in universe { 15 guard let count = wordCount[kv.key], count >= kv.value else { 16 return false 17 } 18 } 19 return true 20 } 21 22 func countCharacters(in word: String) -> [Character: Int] { 23 return word.reduce(into: [:]) { (result, next) in 24 let count = result[next] ?? 0 25 result[next] = count + 1 26 } 27 } 28 }
2484ms
1 class Solution { 2 func wordSubsets(_ A: [String], _ B: [String]) -> [String] { 3 let universe: [Character: Int] = B.reduce(into: [:]) { res, next in 4 let c = countCharacters(in: next) 5 for kv in c { 6 res[kv.key] = max(kv.value, res[kv.key] ?? 0) 7 } 8 } 9 10 return A.filter { (word) -> Bool in 11 return self.isWord(word, universalIn: universe) 12 } 13 } 14 15 func isWord(_ word: String, universalIn universe: [Character: Int]) -> Bool { 16 var wordCount = countCharacters(in: word) 17 for kv in universe { 18 guard let count = wordCount[kv.key], count >= kv.value else { 19 return false 20 } 21 } 22 return true 23 } 24 25 func countCharacters(in word: String) -> [Character: Int] { 26 return word.reduce(into: [:]) { (result, next) in 27 let count = result[next] ?? 0 28 result[next] = count + 1 29 } 30 } 31 }
2652ms
1 class Solution { 2 func wordSubsets(_ A: [String], _ B: [String]) -> [String] { 3 4 let bCounterArray = B 5 .map { 6 $0.reduce(into: [:]) { 7 $0[String($1), default: 0] += 1 8 } 9 } 10 .reduce(into: [:]) { (dict: inout [String: Int], word: [String: Int]) in 11 word.forEach { 12 dict[$0] = (dict[$0] == nil ? $1 : max(dict[$0]!, $1)) 13 } 14 } 15 16 let aCounterDictionary = A.reduce(into: [:]) { 17 $0[$1] = $1.reduce(into: [:]) { 18 $0[String($1), default: 0] += 1 19 } 20 } 21 22 var answer = [String]() 23 24 for (word, aCounter) in aCounterDictionary { 25 var isUniversal = true 26 for (key, bval) in bCounterArray { 27 guard let aval = aCounter[key], aval >= bval else { 28 isUniversal = false 29 break 30 } 31 } 32 33 if isUniversal { 34 answer.append(word) 35 } 36 } 37 38 return answer 39 } 40 }
2708ms
1 class Solution { 2 func wordSubsets(_ A: [String], _ B: [String]) -> [String] { 3 var mb = [Character: Int]() 4 for b1 in B { 5 var d = [Character: Int]() 6 for b2 in b1 { 7 d[b2, default: 0] += 1 8 } 9 for k in d.keys { 10 mb[k, default: 0] = max(mb[k, default: 0], d[k]!) 11 } 12 } 13 //print(mb) 14 return A.filter { s in 15 var d = [Character: Int]() 16 for c in s { 17 d[c, default: 0] += 1 18 } 19 //print(d) 20 for k in mb.keys { 21 guard mb[k]! <= d[k, default: 0] else { 22 return false 23 } 24 } 25 return true 26 } 27 } 28 }
2712ms
1 class Solution { 2 func wordSubsets(_ A: [String], _ B: [String]) -> [String] { 3 var result = [String]() 4 var bMap = [Character : Int]() 5 for bWord in B { 6 var bMapTemp = [Character : Int]() 7 for character in bWord { 8 if let value = bMapTemp[character] { 9 bMapTemp[character] = value + 1 10 } else { 11 bMapTemp[character] = 1 12 } 13 14 if let value1 = bMap[character], let value2 = bMapTemp[character] { 15 bMap[character] = max(value1, value2) 16 } else { 17 bMap[character] = bMapTemp[character] 18 } 19 20 } 21 22 } 23 //print(bMap) 24 for aWord in A { 25 var aMap = [Character : Int]() 26 for character in aWord { 27 if let value = aMap[character] { 28 aMap[character] = value + 1 29 } else { 30 aMap[character] = 1 31 } 32 } 33 34 var shouldAdd = true 35 for (key, value) in bMap { 36 //print("key \(key), value \(value), aMap \(aMap)") 37 guard let aValue = aMap[key] else { 38 shouldAdd = false 39 break 40 } 41 if aValue < value { 42 shouldAdd = false 43 break 44 } 45 } 46 if shouldAdd { 47 result.append(aWord) 48 } 49 } 50 51 return result 52 } 53 }
3208ms
1 class Solution { 2 3 // B = ["o", "oo", "oo", "ooo"] 4 5 func wordSubsets(_ A: [String], _ B: [String]) -> [String] { 6 let reducedSet: [Character: Int] = B.reduce(into: [:]) { res, next in 7 for (k, v) in countCharacters(in: next) { 8 res[k] = max(v, res[k] ?? 0) 9 } 10 } 11 return A.filter { self.isWord($0, universalFor: reducedSet) } 12 } 13 14 func isWord(_ word: String, universalFor characters: [Character: Int]) -> Bool { 15 let characterCount = countCharacters(in: word) 16 return !characters.contains { 17 let count = characterCount[$0.key] 18 return count == nil || count! < $0.value 19 } 20 } 21 22 func countCharacters(in word: String) -> [Character: Int] { 23 return word.reduce(into: [:]) { (result, next) in 24 let count = result[next] ?? 0 25 result[next] = count + 1 26 } 27 } 28 }
3600ms
1 class Solution { 2 3 // B = ["o", "oo", "oo", "ooo"] 4 5 func wordSubsets(_ A: [String], _ B: [String]) -> [String] { 6 let reducedSet: [Character: Int] = B.reduce(into: [:]) { res, next in 7 for (k, v) in countCharacters(in: next) { 8 res[k] = max(v, res[k] ?? 0) 9 } 10 } 11 return A.filter { self.isWord($0, universalFor: reducedSet) } 12 } 13 14 func isWord(_ word: String, universalFor characters: [Character: Int]) -> Bool { 15 let characterCount = countCharacters(in: word) 16 return !characters.contains { 17 let count = characterCount[$0.key] 18 return count == nil || count! < $0.value 19 } 20 } 21 22 func countCharacters(in word: String) -> [Character: Int] { 23 return word.reduce(into: [:]) { (result, next) in 24 let count = result[next] ?? 0 25 result[next] = count + 1 26 } 27 } 28 }