1. 程式人生 > >[Swift]LeetCode211. 新增與搜尋單詞 - 資料結構設計 | Add and Search Word - Data structure design

[Swift]LeetCode211. 新增與搜尋單詞 - 資料結構設計 | Add and Search Word - Data structure design

Design a data structure that supports the following two operations:

void addWord(word)
bool search(word)

search(word) can search a literal word or a regular expression string containing only letters a-z or .. A . means it can represent any one letter.

Example:

addWord("bad")
addWord("dad")
addWord("mad")
search("pad") -> false
search("bad") -> true
search(".ad") -> true
search("b..") -> true

Note:
You may assume that all words are consist of lowercase letters a-z.


設計一個支援以下兩種操作的資料結構:

void addWord(word)
bool search(word)

search(word) 可以搜尋文字或正則表示式字串,字串只包含字母 . 或 a-z 。 . 可以表示任何一個字母。

示例:

addWord("bad")
addWord("dad")
addWord("mad")
search("pad") -> false
search("bad") -> true
search(".ad") -> true
search("b..") -> true

說明:

你可以假設所有單詞都是由小寫字母 a-z 組成的。


612ms

 1 class TrieNode {
 2     var children: [Character: TrieNode]
 3     var isEnd: Bool
 4     
 5     init() {
 6         children = [:]
 7         isEnd = false
 8     }
 9 }
10 
11 class WordDictionary {
12     
13     private var root: TrieNode
14 /** Initialize your data structure here. */ 15 init() { 16 root = TrieNode() 17 } 18 19 /** Adds a word into the data structure. */ 20 func addWord(_ word: String) { 21 var node = self.root 22 23 for c in Array(word) { 24 if let next = node.children[c] { 25 node = next 26 } else { 27 let newNode = TrieNode() 28 node.children[c] = newNode 29 node = newNode 30 } 31 } 32 node.isEnd = true 33 } 34 35 /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */ 36 func search(_ word: String) -> Bool { 37 return self.match(Array(word), 0, self.root) 38 } 39 40 private func match(_ chars: [Character], _ i :Int, _ node: TrieNode) -> Bool { 41 // if we reached the end 42 if i == chars.count { 43 return node.isEnd 44 } 45 let c = chars[i] 46 if c != "." { 47 guard let next = node.children[c] else { return false } 48 return self.match(chars, i + 1, next) 49 } else { 50 for next in node.children.values { 51 if self.match(chars, i + 1, next) { 52 return true 53 } 54 } 55 } 56 57 return false 58 } 59 } 60 61 /** 62 * Your WordDictionary object will be instantiated and called as such: 63 * let obj = WordDictionary() 64 * obj.addWord(word) 65 * let ret_2: Bool = obj.search(word) 66 */

620ms

 1 class WordDictionary {
 2     var trie = Trie()
 3 
 4     /** Initialize your data structure here. */
 5     init() {
 6 
 7     }
 8     
 9     /** Adds a word into the data structure. */
10     func addWord(_ word: String) {
11       trie.add(word: word)
12     }
13     
14     /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */
15     func search(_ word: String) -> Bool {
16       return trie.search(word:word)
17     }
18 }
19 
20 class TrieNode {
21   var children: [Character: TrieNode]
22   var isEnd: Bool
23 
24   init() {
25     self.children = [Character: TrieNode]()
26     self.isEnd = false
27   }
28 }
29 
30 
31 class Trie {
32   var root: TrieNode
33 
34   init() {
35     root = TrieNode()
36   }
37 
38   func add(word: String) {
39     var node = root
40 
41     for char in word {
42       if node.children[char] == nil {
43         node.children[char] = TrieNode()
44       }
45 
46       node = node.children[char]!
47     }
48 
49     node.isEnd = true
50   }
51   
52   func search(word:String) -> Bool {
53     return dfsSearch(word: word, index: 0, node: root)
54   }
55   
56   fileprivate func dfsSearch(word: String, index: Int, node: TrieNode) -> Bool {
57     if index == word.count {
58       return node.isEnd
59     }
60     
61     let char = Array(word)[index]
62     
63     if char != "." {
64       guard let nextNode = node.children[char] else {
65         return false
66       }
67       
68       return dfsSearch(word: word, index: index + 1, node: nextNode)
69     } else{
70       for key in node.children.keys {
71         if dfsSearch(word: word, index: index + 1, node: node.children[key]!) {
72           return true
73         }
74       }
75       
76       return false
77     }
78   }
79 }
80 /**
81  * Your WordDictionary object will be instantiated and called as such:
82  * let obj = WordDictionary()
83  * obj.addWord(word)
84  * let ret_2: Bool = obj.search(word)
85  */
86  

644ms

  1 class TrieNode {
  2     var children = [Character : TrieNode]()
  3     var isEnd = false
  4 }
  5 
  6 
  7 class Trie {
  8     private let root: TrieNode
  9     
 10     /** Initialize your data structure here. */
 11     init() {
 12         root = TrieNode()
 13     }
 14     
 15     /** Inserts a word into the trie. */
 16     func insert(_ word: String) {
 17         var currentNode: TrieNode? = root
 18         for c in word {
 19             if let nextNode = currentNode?.children[c] {
 20                 currentNode = nextNode
 21             } else {
 22                 let newNode = TrieNode()
 23                 
 24                 currentNode?.children[c] = newNode
 25                 currentNode = newNode
 26             }
 27         }
 28         
 29         currentNode?.isEnd = true
 30     }
 31     
 32     /** Returns if the word is in the trie. */
 33     func search(_ word: String) -> Bool {
 34         return searchNode(root, word: word, index: word.startIndex)
 35     }
 36     
 37     func searchNode(_ node: TrieNode, word: String, index: String.Index) -> Bool {
 38         if index == word.endIndex {
 39             return node.isEnd
 40         }
 41         
 42         var currentNode: TrieNode? = root
 43         let char = word[index]
 44         if char == "." {
 45             for (_, n) in node.children {
 46                 if searchNode(n, word: word, index: word.index(after: index)) {
 47                     return true
 48                 }
 49             }
 50             
 51             return false
 52         } else {
 53             guard let nextNode = node.children[char] else {
 54                 return false
 55             }
 56 
 57             return searchNode(nextNode, word: word, index: word.index(after: index))
 58         }
 59     }
 60     
 61     /** Returns if there is any word in the trie that starts with the given prefix. */
 62     func startsWith(_ prefix: String) -> Bool {
 63       var currentNode: TrieNode? = root
 64         for c in prefix {
 65             guard let nextNode = currentNode?.children[c] else {
 66                 return false
 67             }
 68             
 69             currentNode = nextNode
 70         }
 71         
 72         return true
 73     }
 74 }
 75 
 76 
 77 class WordDictionary {
 78     private let trie = Trie()
 79     
 80     
 81     /** Initialize your data structure here. */
 82     init() {
 83         
 84     }
 85     
 86     /** Adds a word into the data structure. */
 87     func addWord(_ word: String) {
 88         trie.insert(word)
 89     }
 90     
 91     /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */
 92     func search(_ word: String) -> Bool {
 93         return trie.search(word)
 94     }
 95 }
 96 
 97 /**
 98  * Your WordDictionary object will be instantiated and called as such:
 99  * let obj = WordDictionary()
100  * obj.addWord(word)
101  * let ret_2: Bool = obj.search(word)
102  */
103  

756ms

 1 class WordDictionary {
 2     var trie = Trie()
 3     /** Initialize your data structure here. */
 4     init() {
 5         
 6     }
 7     
 8     /** Adds a word into the data structure. */
 9     func addWord(_ word: String) {
10         trie.insert(word)
11     }
12     
13     /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */
14     func search(_ word: String) -> Bool {
15         return trie.search(word, 0, trie.root)
16     }
17 }
18 
19 class TrieNode {
20     var isWord = false
21     var next = [Character: TrieNode]()
22     init(_ b: Bool = false) {
23         isWord = b
24     }
25 }
26 
27 class Trie {
28     var root = TrieNode()
29     func insert(_ word: String) {
30         var cur = root
31         for c in word {
32             if cur.next[c] == nil {
33                 cur.next[c] = TrieNode()
34             }
35             cur = cur.next[c]!
36         }
37         cur.isWord = true
38     }
39     
40     func search(_ word: String, _ idx: Int, _ node: TrieNode) -> Bool {
41         var cur = node
42         var chars = Array(word)
43         for i in idx..<chars.count {
44             if let n = cur.next[chars[i]] {
45                 cur = n
46             } else if chars[i] != "." {
47                 return false
48             } else {
49                 for n in cur.next.values {
50                     if search(word, i+1, n) {
51                         return true
52                     }
53                 }
54                 return false
55             }
56         }
57         return cur.isWord
58     }
59 }
60 
61 /**
62  * Your WordDictionary object will be instantiated and called as such:
63  * let obj = WordDictionary()
64  * obj.addWord(word)
65  * let ret_2: Bool = obj.search(word)
66  */
67  

764ms

 1 class Trie {
 2     var char: Character
 3     var children: [Character :Trie]
 4     
 5     init(_ char: Character) {
 6         self.char = char
 7         self.children = [:]
 8     }
 9 }
10 
11 class WordDictionary {
12     var root: Trie
13     /** Initialize your data structure here. */
14     init() {
15         self.root = Trie(Character(".")) 
16     }
17     
18     /** Adds a word into the data structure. */
19     func addWord(_ word: String) {
20         var temp = root
21         for char in word {
22             if let child = temp.children[char] {
23                 temp = child
24             } else {
25                 let newNode = Trie(char)
26                 temp.children[char] = newNode
27                 temp = newNode
28             }
29         }
30         let newNode = Trie("$")
31         temp.children["$"] = newNode
32         temp = newNode
33     }
34     
35     /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */
36     func search(_ word: String) -> Bool {
37         return searchInternal(word, self.root)
38     }
39     
40     private func searchInternal(_ word: String, _ node:Trie) -> Bool {
41         // print("Searching word : \(word)")
42         if word.isEmpty {
43             // print("Valid!!!!!!")
44             if let child = node.children["$"] {
45                 return true
46             } else {
47                 return false
48             }
49         }
50         let firstChar = word[word.index(word.startIndex, offsetBy: 0)]
51         let trimmedWord = String(word[word.index(word.startIndex, offsetBy: 1)..<word.endIndex])
52         if firstChar == "." {
53             for child in node.children {
54                 let isValidNode = self.searchInternal(trimmedWord, child.value)
55                 if isValidNode {
56                     return true
57                     break
58                 }
59             }
60         } else {
61             if let child = node.children[firstChar] {
62                 return self.searchInternal(trimmedWord, child)
63             } else {
64                 // print("not valid1")
65                 return false
66             }
67         }
68         // print("not valid0")
69         return false
70     }
71 }
72 
73 /**
74  * Your WordDictionary object will be instantiated and called as such:
75  * let obj = WordDictionary()
76  * obj.addWord(word)
77  * let ret_2: Bool = obj.search(word)
78  */
79