1. 程式人生 > >[Swift]LeetCode336. 回文對 | Palindrome Pairs

[Swift]LeetCode336. 回文對 | Palindrome Pairs

拼接 plan ted ict point lse tab add exp

Given a list of unique words, find all pairs of distinct indices (i, j) in the given list, so that the concatenation of the two words, i.e. words[i] + words[j] is a palindrome.

Example 1:

Input: ["abcd","dcba","lls","s","sssll"]
Output: [[0,1],[1,0],[3,2],[2,4]] 
Explanation: The palindromes are ["dcbaabcd","abcddcba","slls","llssssll"]

Example 2:

Input: ["bat","tab","cat"]
Output: [[0,1],[1,0]] 
Explanation: The palindromes are ["battab","tabbat"]

給定一組唯一的單詞, 找出所有不同 的索引對(i, j),使得列表中的兩個單詞, words[i] + words[j] ,可拼接成回文串。

示例 1:

輸入: ["abcd","dcba","lls","s","sssll"]
輸出: [[0,1],[1,0],[3,2],[2,4]] 
解釋: 可拼接成的回文串為 ["dcbaabcd","abcddcba","slls","llssssll"]

示例 2:

輸入: ["bat","tab","cat"]
輸出: [[0,1],[1,0]] 
解釋: 可拼接成的回文串為 ["battab","tabbat"]

1068ms
 1 class Solution {
 2     class TridNode {
 3         var nexts : [Character : TridNode] = [Character : TridNode]()
 4         var index : Int = -1
 5         var parIndexs = [Int]()
 6     }
 7
8 func palindromePairs(_ words: [String]) -> [[Int]] { 9 10 var res = [[Int]]() 11 12 let root = TridNode() 13 14 for i in 0..<words.count { 15 buildTrees(root, Array(words[i]), i) 16 } 17 18 for i in 0..<words.count { 19 search(Array(words[i]), i, root, &res) 20 } 21 22 return res 23 } 24 25 func buildTrees(_ root : TridNode, _ wordArr : [Character] , _ index : Int ) { 26 var root = root 27 for i in stride(from: wordArr.count - 1, to: -1, by: -1) { 28 let c = wordArr[i] 29 if root.nexts[c] == nil { 30 root.nexts[c] = TridNode() 31 } 32 if isPalindrome(wordArr, 0, i) { 33 root.parIndexs.append(index) 34 } 35 36 root = root.nexts[c]! 37 } 38 39 root.parIndexs.append(index) 40 root.index = index 41 } 42 43 func search(_ wordArr : [Character], _ i : Int , _ root : TridNode , _ res : inout [[Int]]) { 44 var root = root 45 for j in 0..<wordArr.count { 46 if root.index >= 0 && root.index != i && isPalindrome(wordArr, j, wordArr.count - 1) { 47 res.append([i,root.index]) 48 } 49 50 guard root.nexts[wordArr[j]] != nil else { 51 return 52 } 53 54 root = root.nexts[wordArr[j]]! 55 } 56 57 for j in root.parIndexs where i != j { 58 res.append([i,j]) 59 } 60 61 } 62 63 64 func isPalindrome(_ wordArr : [Character], _ i : Int , _ j : Int) -> Bool { 65 66 var i = i, j = j 67 68 while i < j { 69 if wordArr[i] != wordArr[j] { 70 return false 71 } 72 i += 1 73 j -= 1 74 } 75 76 return true 77 } 78 }

1280ms

 1 class Solution {
 2     let lowerLetterUnicodeStart = Character("a").char2Int()
 3 
 4     func palindromePairs(_ words: [String]) -> [[Int]] {
 5         var result = [[Int]]()
 6         let n = words.count
 7         let root = TrieNode()
 8 
 9         func addWord(_ root: TrieNode, _ index: Int) {
10             var point = root
11             let word = Array(words[index])
12             for i in (0..<word.count).reversed() {
13                 let char = word[i].char2Int() - lowerLetterUnicodeStart
14                 if point.next[char] == nil { point.next[char] = TrieNode() }
15                 if isPalindrome(word, 0, i) { point.list.append(index) }
16                 if let next = point.next[char] { point = next }
17             }
18             point.list.append(index)
19             point.index = index
20         }
21 
22         func search(_ root: TrieNode, _ index: Int) {
23             var point = root
24             let word = Array(words[index])
25             for i in 0..<word.count {
26                 let idx = point.index
27                 if idx >= 0, idx != index, isPalindrome(word, i, word.count - 1) {
28                         result.append([index, idx])
29                     
30                 }
31                 let char = word[i].char2Int() - lowerLetterUnicodeStart
32                 if let next = point.next[char] { point = next } else { return }
33             }
34             for i in point.list where index != i { result.append([index, i]) }
35         }
36 
37         for i in 0..<n { addWord(root, i) }
38         for i in 0..<n { search(root, i) }
39         return result
40     }
41 
42     func isPalindrome(_ word: [Character], _ i: Int, _ j: Int) -> Bool {
43         var (i, j) = (i, j)
44         while i < j {
45             if word[i] != word[j] { return false }
46             i += 1
47             j -= 1
48         }
49         return true
50     }
51 }
52 
53 class TrieNode {
54     var next: [TrieNode?] = Array(repeating: nil, count: 26)
55     var index = -1
56     var list = [Int]()
57 }
58 
59 extension Character {
60     func char2Int() -> Int {
61         return Int(self.unicodeScalars.first!.value)
62     }
63 }

1516ms

  1 class Solution {
  2     func palindromePairs(_ words: [String]) -> [[Int]] {
  3         var rslts = [[Int]]()
  4         if words.count == 0 {
  5             return rslts
  6         }
  7         
  8         class Node {
  9             var label: Int?
 10             var dict: [Character: Node]
 11             
 12             init() {
 13                 label = nil
 14                 dict = [:]
 15             }
 16             
 17             func isPalindrome(_ charArr: [Character], from index: Int) -> Bool {
 18                 if index >= charArr.count {
 19                     return true
 20                 }
 21             
 22                 var left = index
 23                 var right = charArr.count-1
 24             
 25                 while left < right {
 26                     let lch = charArr[left]
 27                     let rch = charArr[right]
 28                     if lch != rch {
 29                         return false
 30                     }
 31                     left += 1
 32                     right -= 1
 33                 }
 34                 return true
 35             }
 36             
 37             func insert(_ charArr: [Character], _ index: Int, _ label: Int) -> Void {
 38                 // print("insert", index)
 39                 if index >= charArr.count {
 40                     self.label = label
 41                     return
 42                 }
 43                 
 44                 let ch = charArr[index]
 45                 var node = dict[ch]
 46                 if node == nil {
 47                     node = Node()
 48                     dict[ch] = node
 49                 }
 50                 node?.insert(charArr, index+1, label)
 51             }
 52             
 53             func search(_ charArr: [Character], _ index: Int, _ mLabel: Int, _ labels: inout [Int]) -> Void {
 54                 // print("search", index)     
 55                 if let label = label, label != mLabel {
 56                     if isPalindrome(charArr, from: index) == true {
 57                         labels.append(label)     
 58                     }
 59                 }
 60                 
 61                 if index >= charArr.count {
 62                     return
 63                 }
 64                                 
 65                 let ch = charArr[index]
 66                 guard let node = dict[ch] else {
 67                     return
 68                 }
 69                 node.search(charArr, index+1, mLabel, &labels)
 70             }
 71         }
 72         
 73         var trie = Node()
 74         for (i, word) in words.enumerated() {
 75             trie.insert(Array(word), 0, i)
 76         }
 77         
 78         for (i, word) in words.enumerated() {
 79             var labels = [Int]()
 80             trie.search(Array(word.reversed()), 0, i, &labels)
 81             for label in labels {
 82                 rslts.append([label, i])
 83             }
 84         }
 85         
 86         trie = Node()
 87         for (i, word) in words.enumerated() {
 88             trie.insert(Array(word.reversed()), 0, i)
 89         }
 90         
 91         for (i, word) in words.enumerated() {
 92             var labels = [Int]()
 93             trie.search(Array(word), 0, i, &labels)
 94             for label in labels {
 95                 rslts.append([i, label])
 96             }
 97         }
 98         return Array(Set(rslts))
 99     }
100 }

4620ms

 1 class Solution {
 2     func palindromePairs(_ words: [String]) -> [[Int]] {
 3         var wd = [String : Int]()
 4         var ld = Set<Int>()
 5         var res = [[Int]]()
 6         for (i, word) in words.enumerated() {
 7             wd[word] = i
 8             ld.insert(word.count)
 9         }
10         
11         for i in 0 ..< words.count {
12             var word = words[i]
13             var reword = String(word.reversed())
14             if let index = wd[reword], index != i {
15                 res.append([i, index])
16             }
17             var w1 = Array(word)
18             for l in 0 ..< w1.count {
19                 if ld.contains(l) {
20                     if l == 0 && isValid(w1, 0, w1.count-1) {
21                         res.append([i, wd[""]!])
22                         res.append([wd[""]!, i])
23                     } else {
24                         if let index = wd[String(Array(w1[0 ..< l]).reversed())], isValid(w1, l, w1.count-1) {
25                             res.append([i, index])
26                         }
27                         if let index = wd[String(Array(w1[w1.count-l ..< w1.count]).reversed())], isValid(w1, 0, w1.count-l-1) {
28                             res.append([index, i])
29                         }  
30                     } 
31                 }
32             }
33         }
34         return res
35     }
36     
37     func isValid(_ w: [Character], _ left: Int, _ right: Int) -> Bool {
38         var l = left
39         var r = right
40         while l <= r {
41             if w[l] != w[r] {
42                 return false
43             } else {
44                 l += 1
45                 r -= 1
46             }
47         }
48         return true
49     }
50 }

7924ms

 1 class Solution {
 2     
 3     func palindromePairs(_ words: [String]) -> [[Int]] {
 4         var indexes = [String: Int]()
 5         var result = [[Int]]()
 6         for (i, w) in words.enumerated() {
 7             indexes[w] = i
 8         }
 9         for (i, w) in words.enumerated() {
10             for j in (0...w.count) {
11                 let prefix = subword(w, 0..<j)
12                 let suffix = subword(w, j..<w.count)
13                 if isPalindrome(prefix) {
14                     let end = String(suffix.reversed())
15                     if end != w, let index = indexes[end] {
16                         result.append([index, i])
17                     }
18                 }
19                 if j != w.count && isPalindrome(suffix) {
20                     let end = String(prefix.reversed())
21                     if end != w, let index = indexes[end] {
22                         result.append([i, index])
23                     }
24                 }
25             }
26         }
27         
28         return result
29     }
30     
31     func isPalindrome(_ word: String) -> Bool {
32         return String(word.reversed()) == word
33     }
34     
35     func subword(_ word: String, _ range: Range<Int>) -> String {
36         return Array(word)[range].map { String($0) }.joined(separator: "")
37     }
38 }

[Swift]LeetCode336. 回文對 | Palindrome Pairs