Leetcode336. 回文对 (Python3测试通过)

一、题目描述:

给定一组互不相同的单词, 找出所有不同的索引对 (i, j),使得列表中的两个单词words[i] + words[j],可拼接成回文串。

  1. 示例 1:

    • 输入:words = [“abcd”,“dcba”,“lls”,“s”,“sssll”]
    • 输出:[[0,1],[1,0],[3,2],[2,4]]
    • 解释:可拼接成的回文串为 [“dcbaabcd”,“abcddcba”,“slls”,“llssssll”]
  2. 示例 2:

    • 输入:words = [“a”,“”]
    • 输出:[[0,1],[1,0]]
  3. 提示:

    • 1 <= words.length <= 5000
    • 0 <= words[i].length <= 300
    • words[i]由小写英文字母组成

二、解决思路和代码

解法一:暴力解决
思路

两层循环遍历words中所有的字符串,每次遍历取两个不同的字符串进行拼接,然后判断拼接后的字符串是否是回文串。如果是,增加两个字符串的索引对。

代码
from typing import List

class Solution:
    def Ispalindrome(self, s: str) -> bool:
        left, right = 0, len(s)-1
        while left<right and s[left]==s[right]:
            left+=1
            right-=1
        return True if left>=right else False
        
    def palindromePairs(self, words: List[str]) -> List[List[int]]:
        res = []
        for i in range(len(words)):
            for j in range(i+1, len(words)):
                if self.Ispalindrome(words[i]+words[j]):
                    res.append([i,j])
                    if len(words[i])==len(words[j]):
                        res.append([j,i])
                        continue
                if self.Ispalindrome(words[j]+words[i]):
                    res.append([j,i])
        return res
解法二:利用前后缀解决
思路
  • 回文串的特点是:基于轴中心对称

    • 轴中心
      • 比如回文串:“abcddcba”
        • 轴中心取’dd’,"abc"和"cba"对称
        • 轴中心取’cddc’,"ab"和"ba"对称
      • 比如回文串:“abcdcba”
        • 轴中心取’d’,"abc"和"cba"对称
        • 轴中心取’cdc’,"ab"和"ba"对称
    • 轴中心字符串的特点:反转相等/回文串
  • 理解为:给定字符串’sssll’,找到字符串x,可以与’sssll’拼接为回文串

    1. 中心取’’
      • 中心反转相等,‘sssll’的对称字符串是’llsss’
    2. 中心=‘s’
      • 中心反转相等,‘ssll’的对称字符串是’llsss’
    3. 中心=‘ss’
      • 中心反转相等,‘sll’的对称字符串是’lls’
    4. 中心=‘sss’
      • 中心反转相等,‘ll’的对称字符串是’ll’
    5. 中心=‘sssl’
      • 中心反转不相等
    6. 中心=‘sssll’
      • 中心反转不相等
  • 理解为:将回文串划分为三部分:left, 轴中心, right。而在words中,给定left+轴中心,找right=left的反转;或给定right+轴中心,找left=right的反转

代码
from typing import List
class Solution:
    def palindromePairs(self, words: List[str]) -> List[List[int]]:
        rev_words = {}
        for idx, word in enumerate(words):
            rev_words[word[::-1]] = idx
        
        res = []
        for idx, word in enumerate(words):
            if word:
                for i in range(len(word)+1):
                    left, right = word[:i], word[i:]
                    if right == right[::-1]:
                        pos = rev_words.get(left,-1)
                        if pos!=-1 and pos!=idx:
                            res.append([idx, pos])
                    if i!=0 and left == left[::-1]:
                        pos = rev_words.get(right,-1)
                        if pos!=-1 and pos!=idx:
                            res.append([pos, idx])
        return res

测试通过
在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值