• 09 -- 回文对


    目录

    一、什么是回文对

    二、题目

    三、解题思路

    回文+翻转

     两层for循环


    Github链接


    一、什么是回文对

    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数组中所有的字符串先翻转一遍,然后再放到一个字典中[String: Int]
    • 对words数组进行遍历
    • 如果遍历到是空数组,并且字典中含有key是回文对的,那么就加入答案中
    • 复杂度:O(n^2)

    例如:

    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]]     

    代码:

    1. //字典方法
    2. func palindromePairs(_ words: [String]) -> [[Int]] {
    3. var dict = [String: Int]()
    4. var res = [[Int]]()
    5. words.enumerated().forEach { (index, str) in
    6. dict[String(str.reversed())] = index
    7. }
    8. for (index, s) in words.enumerated() {
    9. if s.isEmpty {
    10. dict.forEach { (Str, idx) in
    11. if checkIsOK(Str) && index != idx {
    12. res.append([index,idx])
    13. }
    14. }
    15. }
    16. for j in 0..<s.count {
    17. let mid = s.index(s.startIndex, offsetBy: j)
    18. let leftPart = String(s[..<mid])
    19. let rightPart = String(s[mid...])
    20. if checkIsOK(leftPart) && dict[rightPart] != nil && dict[rightPart] != index {
    21. res.append([dict[rightPart]!, index])
    22. }
    23. if checkIsOK(rightPart) && dict[leftPart] != nil && dict[leftPart] != index {
    24. res.append([index, dict[leftPart]!])
    25. }
    26. }
    27. }
    28. return res
    29. }
    30. func checkIsOK(_ s: String) -> Bool {
    31. return s == String(s.reversed())
    32. }

     两层for循环

    逐个字符串相加,然后再尝试左右方向调整,拼接新字符串,判断新字符串是否是回文对,这种思路相对容易理解

    复杂度: O(n^2)

    代码:

    1. // 拼接方法
    2. func palindromePairsTimeout(_ words: [String]) -> [[Int]] {
    3. let n = words.count
    4. var res = [[Int]]()
    5. for i in 0..<n-1 {
    6. let str1 = words[i]
    7. for j in i+1..<n {
    8. let str2 = words[j]
    9. if checkIsOK(str1 + str2) {
    10. res.append([i,j])
    11. }
    12. if checkIsOK(str2 + str1) {
    13. res.append([j,i])
    14. }
    15. }
    16. }
    17. return res
    18. }
    19. func checkIsOK(_ s: String) -> Bool {
    20. return s == String(s.reversed())
    21. }

  • 相关阅读:
    AC自动机
    ElasticSearch学习(Part One,语法学习)
    关于开源和闭源
    protobuf语法之proto2简述
    C语言刷题(2)
    二叉搜索树 - C++ 实现
    shell编程基础
    EM@运动轨迹曲线和参数方程
    算法与数据结构【30天】集训营——B树的创建、查找、插入、删除总结的最佳解决方法(17)
    Spring和SpringBoot比较,解惑区别
  • 原文地址:https://blog.csdn.net/JH_Cao/article/details/125417412