目录
1. 回文对,就是对称的字符串,比如
"a"
"aba"
"aabb"
给定一组 互不相同 的单词, 找出所有 不同 的索引对 (i, j),使得列表中的两个单词, words[i] + words[j] ,可拼接成回文串。
示例 1:
输入:words = ["abcd","dcba","lls","s","sssll"]
输出:[[0,1],[1,0],[3,2],[2,4]]
解释:可拼接成的回文串为 ["dcbaabcd","abcddcba","slls","llssssll"]
例如:
1. words翻转,加入字典,那么将会得到字典
[["dcba": 0], ["abcd": 1], ["sll": 2], ["s": 3], ["llsss": 4]]
2. 对数组words = ["abcd","dcba","lls","s","sssll"]进行遍历
(1) 举例当前下标为2,则字符串为“lls”
从下标为0开始,进行分割,
left = "" , right = "lls",虽然left为回文对,但 字典中没有“lls”为key,继续分割
left = "l", right = "ls", 虽然left为回文对,但字典中没有“ls”为key, 继续分割
left = "ll", right = "s", left回文对,字典中也包含“s”为key,当前下标index = 2
["s": 3]中的value = 3
因为对称的那一段(left),必须放中间,拼接起来的新字符串才可以也是回文对
所以当前下标的字符串放在后面
那么 [3 , 2] 下标组成的字符串为 “s” + "lls" == “slls”, 是回文对
(2) 举例当前下标为4,则字符串为“sssll”
从下标为0开始,进行分割,
left = "" , right = "sssll",虽然left为回文对,但 字典中没有“sssll”为key,继续分割
left = "s", right = "ssll", 虽然left为回文对,但字典中没有“ssll”为key, 继续分割
left = "ss", right = "sll", left回文对,字典中也包含“sll”为key,当前下标index = 4
["sll": 2]中的value = 2
同理:
因为对称的那一段(left),必须放中间,拼接起来的新字符串才可以也是回文对
所以当前下标的字符串放在后面
那么 [2, 4] => lls + sssll + = llssssll => 是回文对
(3)同理:
如果对称的那一段是(right)部分,那么当前下标的字符串要放前面
组合起来就是[ index, dict[right]]
代码:
- //字典方法
- func palindromePairs(_ words: [String]) -> [[Int]] {
- var dict = [String: Int]()
- var res = [[Int]]()
-
- words.enumerated().forEach { (index, str) in
- dict[String(str.reversed())] = index
- }
-
- for (index, s) in words.enumerated() {
- if s.isEmpty {
- dict.forEach { (Str, idx) in
- if checkIsOK(Str) && index != idx {
- res.append([index,idx])
- }
- }
- }
-
- for j in 0..<s.count {
- let mid = s.index(s.startIndex, offsetBy: j)
- let leftPart = String(s[..<mid])
- let rightPart = String(s[mid...])
-
- if checkIsOK(leftPart) && dict[rightPart] != nil && dict[rightPart] != index {
- res.append([dict[rightPart]!, index])
- }
- if checkIsOK(rightPart) && dict[leftPart] != nil && dict[leftPart] != index {
- res.append([index, dict[leftPart]!])
- }
- }
- }
-
- return res
- }
-
- func checkIsOK(_ s: String) -> Bool {
- return s == String(s.reversed())
- }
逐个字符串相加,然后再尝试左右方向调整,拼接新字符串,判断新字符串是否是回文对,这种思路相对容易理解
复杂度: O(n^2)
代码:
- // 拼接方法
- func palindromePairsTimeout(_ words: [String]) -> [[Int]] {
- let n = words.count
- var res = [[Int]]()
-
- for i in 0..<n-1 {
- let str1 = words[i]
- for j in i+1..<n {
- let str2 = words[j]
- if checkIsOK(str1 + str2) {
- res.append([i,j])
- }
- if checkIsOK(str2 + str1) {
- res.append([j,i])
- }
- }
- }
-
- return res
- }
-
- func checkIsOK(_ s: String) -> Bool {
- return s == String(s.reversed())
- }