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

代码:

//字典方法
    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())
    }

 两层for循环

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

复杂度: 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())
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值