zoukankan      html  css  js  c++  java
  • [Swift]LeetCode1178. 猜字谜 | Number of Valid Words for Each Puzzle

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

    With respect to a given puzzle string, a word is valid if both the following conditions are satisfied:

    • word contains the first letter of puzzle.
    • For each letter in word, that letter is in puzzle.
      For example, if the puzzle is "abcdefg", then valid words are "faced", "cabbage", and "baggage"; while invalid words are "beefed" (doesn't include "a") and "based" (includes "s" which isn't in the puzzle).

    Return an array answer, where answer[i] is the number of words in the given word list words that are valid with respect to the puzzle puzzles[i].

    Example :

    Input: 
    words = ["aaaa","asas","able","ability","actt","actor","access"], 
    puzzles = ["aboveyz","abrodyz","abslute","absoryz","actresz","gaswxyz"]
    Output: [1,1,3,2,4,0]
    Explanation:
    1 valid word for "aboveyz" : "aaaa" 
    1 valid word for "abrodyz" : "aaaa"
    3 valid words for "abslute" : "aaaa", "asas", "able"
    2 valid words for "absoryz" : "aaaa", "asas"
    4 valid words for "actresz" : "aaaa", "asas", "actt", "access"
    There're no valid words for "gaswxyz" cause none of the words in the list contains letter 'g'.
    

    Constraints:

    • 1 <= words.length <= 10^5
    • 4 <= words[i].length <= 50
    • 1 <= puzzles.length <= 10^4
    • puzzles[i].length == 7
    • words[i][j]puzzles[i][j] are English lowercase letters.
    • Each puzzles[i] doesn't contain repeated characters.

     外国友人仿照中国字谜设计了一个英文版猜字谜小游戏,请你来猜猜看吧。

    字谜的迷面 puzzle 按字符串形式给出,如果一个单词 word 符合下面两个条件,那么它就可以算作谜底:

    • 单词 word 中包含谜面 puzzle 的第一个字母。
    • 单词 word 中的每一个字母都可以在谜面 puzzle 中找到。
      例如,如果字谜的谜面是 "abcdefg",那么可以作为谜底的单词有 "faced", "cabbage", 和 "baggage";而 "beefed"(不含字母 "a")以及 "based"(其中的 "s" 没有出现在谜面中)。

    返回一个答案数组 answer,数组中的每个元素 answer[i] 是在给出的单词列表 words 中可以作为字谜迷面 puzzles[i] 所对应的谜底的单词数目。

    示例:

    输入:
    words = ["aaaa","asas","able","ability","actt","actor","access"], 
    puzzles = ["aboveyz","abrodyz","abslute","absoryz","actresz","gaswxyz"]
    输出:[1,1,3,2,4,0]
    解释:
    1 个单词可以作为 "aboveyz" 的谜底 : "aaaa" 
    1 个单词可以作为 "abrodyz" 的谜底 : "aaaa"
    3 个单词可以作为 "abslute" 的谜底 : "aaaa", "asas", "able"
    2 个单词可以作为 "absoryz" 的谜底 : "aaaa", "asas"
    4 个单词可以作为 "actresz" 的谜底 : "aaaa", "asas", "actt", "access"
    没有单词可以作为 "gaswxyz" 的谜底,因为列表中的单词都不含字母 'g'。
    

    提示:

    • 1 <= words.length <= 10^5
    • 4 <= words[i].length <= 50
    • 1 <= puzzles.length <= 10^4
    • puzzles[i].length == 7
    • words[i][j]puzzles[i][j] 都是小写英文字母。
    • 每个 puzzles[i] 所包含的字符都不重复。

    Runtime: 656 ms
    Memory Usage: 36.7 MB
     1 class Solution {
     2     func findNumOfValidWords(_ words: [String], _ puzzles: [String]) -> [Int] {
     3         var result:[Int] = [Int]()
     4         var wordSets:[Int:Int] = [Int:Int]()
     5         var puzzles = puzzles.map{Array($0).map{$0.ascii}}
     6         var words = words.map{Array($0).map{$0.ascii - 97}}
     7         // Encode word of 26 chars in 31 bit (signed Int)
     8         for i in 0..<words.count
     9         {
    10             var bits:Int = 0
    11             for j in 0..<words[i].count
    12             {
    13                 bits |= 1 << words[i][j]
    14             }
    15             wordSets[bits,default:0] += 1
    16         }
    17 
    18         for i in 0..<puzzles.count
    19         {
    20             var bits:Int = 0
    21             var firstCharBitSet = 1 << (puzzles[i][0] - 97)
    22             for j in 0..<puzzles[i].count
    23             {
    24                 bits |= 1 << (puzzles[i][j] - 97)
    25             }
    26             var count:Int = 0
    27             var b:Int = bits
    28             while(b > 0)
    29             {
    30                 if (b & firstCharBitSet) != 0 && wordSets[b] != nil
    31                 {
    32                     count += wordSets[b]!
    33                 }
    34                 b = --b & bits
    35             }
    36             result.append(count)
    37         }
    38         return result
    39     }
    40 }
    41 
    42 //Character扩展 
    43 extension Character  
    44 {  
    45   //Character转ASCII整数值(定义小写为整数值)
    46    var ascii: Int {
    47        get {
    48            return Int(self.unicodeScalars.first?.value ?? 0)
    49        }       
    50     }
    51 }
    52     
    53 /*扩展Int类,实现自增++、自减--运算符*/
    54 extension Int{
    55     //--前缀:先自减再执行表达示
    56     static prefix func --(num:inout Int) -> Int {
    57         //输入输出参数num
    58         num -= 1
    59         //返回减1后的数值
    60         return num
    61     }
    62 }

    1020ms

     1 class Solution {
     2     func findNumOfValidWords(_ words: [String], _ puzzles: [String]) -> [Int] {        
     3         let table = Array("abcdefghijklmnopqrstuvwxyz")
     4         var dic = [Character: Int](), i = 0
     5         for c in table {
     6             dic[c] = i
     7             i += 1
     8         }
     9         var ans = [Int]()
    10         var freq = [Int](repeating: 0, count: 1<<26)
    11         for w in words {
    12             let cw = Array(w)
    13             var mask = 0
    14             for c in cw {
    15                 mask |= 1<<dic[c]!
    16             }
    17             freq[mask] += 1
    18         }
    19         for p in puzzles {
    20             let cp = Array(p)
    21             var mask = 0
    22             for c in cp {
    23                 mask |= 1<<dic[c]!
    24             }
    25 
    26             let first = dic[cp.first!]!
    27             var sub = mask
    28             var total = 0
    29             while true {
    30                 if sub >> first & 1 != 0 {
    31                     total += freq[sub]
    32                 }
    33                 if sub == 0 {
    34                     break
    35                 }
    36                 sub = (sub-1)&mask
    37             }
    38             ans.append(total)
    39         }
    40         return ans
    41     }
    42 }

    1908ms

     1 class Solution {
     2     func findNumOfValidWords(_ words: [String], _ puzzles: [String]) -> [Int] {
     3         let trie = Trie()
     4         var result = [Int]()
     5         
     6         for word in words {
     7             trie.insert(String(Set(word).sorted()))
     8         }
     9         
    10         for puzzle in puzzles {
    11             let firstCharacter = puzzle[String.Index(encodedOffset: 0)]
    12             let sortedPuzzle = String(puzzle.sorted())
    13             
    14             result.append(trie.search(sortedPuzzle, firstCharacter, false))
    15         }
    16         
    17         return result
    18     }
    19 }
    20 
    21 class TrieNode {
    22     var hash = [Character:TrieNode]()
    23     var countOfWords = 0
    24     
    25     func search(_ word: String, _ firstChar: Character, _ firstSeen: Bool) -> Int {
    26         var count = 0
    27         
    28         if firstSeen { 
    29             count += countOfWords 
    30         }
    31         
    32         for i in 0..<word.count {
    33             let wordChar = word[String.Index(encodedOffset: i)]
    34             
    35             guard let childNode = hash[wordChar] else { continue }
    36             
    37             if wordChar == firstChar {
    38                 count += childNode.search(word, firstChar, true)
    39             } else {
    40                 count += childNode.search(word, firstChar, firstSeen)
    41             }
    42             
    43         }
    44         
    45         return count
    46     }
    47 }
    48 
    49 class Trie {
    50     let root = TrieNode()
    51     
    52     init(_ words: [String] = []) {
    53         words.forEach(insert)
    54     }
    55     
    56     func search(_ word: String, _ firstChar: Character, _ firstSeen: Bool) -> Int {
    57         return root.search(word, firstChar, firstSeen)
    58     }
    59     
    60     func insert(_ word: String) {
    61         var current = root
    62         for character in word {
    63             if let node = current.hash[character] {
    64                 current = node
    65             } else {
    66                 current.hash[character] = TrieNode()
    67                 current = current.hash[character]!
    68             }
    69         }
    70         current.countOfWords += 1
    71     }
    72 }
  • 相关阅读:
    因host命令导致无法正常SHUTDOWN的实验
    ORACLE SEQUENCE 介绍
    SQL Server数据库附加失败:错误5120和错误950
    Java中怎样由枚举常量的ordinal值获得枚举常量对象
    后会终无期,且行且珍惜
    Objective-C辛格尔顿
    自己动手写一个编译器Tiny语言解析器实现
    linux于test 订购具体解释
    Linux高性能server规划——处理池和线程池
    《采访中收集程序猿》学习记录8
  • 原文地址:https://www.cnblogs.com/strengthen/p/11443478.html
Copyright © 2011-2022 走看看