LeetCode(336):回文对 Palindrome Pairs(Java)

2019.11.22 LeetCode 从零单刷个人笔记整理(持续更新)

github:https://github.com/ChopinXBP/LeetCode-Babel

这道题本质上是要切分字符串,使得字典中的两个单词

word1[0,end] + word2[0,j-1] + word2[j,end]
或者
word1[0,j-1] + word1[j,end] + word2[0,end]

恰能构成回文串。

也就是需要word1[0,end]与word2[j,end]互为翻转,且word2[0,j-1]能够构成回文子串(或word1[0,j-1]与word2[0,end]互为翻转,word1[j,end]构成回文子串)。

当j=0时,中间部分为空串,字典中恰有两个单词互为翻转。

因此,可以有两种思路:

1.字典树

从后往前反方向遍历所有单词,构建一棵后缀树(存储翻转的单词)。后缀树的有两个额外成员:reverseWordIdx用于存放翻转单词的单词序号,容器palindPrefixWords存放该结点处除去后缀其余部分能形成回文前缀[0,i]的单词序号。

从前往后遍历单词curWord的进行校验。

如果字典中恰存在一个与curWord[0,j-1]互为翻转的单词reverseWord,且剩余部分curWord[j,end]恰为回文子串,则一定能组合成

curWord[0,j-1]+curWord[j,end]+reverseWord[0,end]

的回文串。

若遍历结束结点仍不空,说明curWord[0,end]恰与字典中其他单词的部分后缀[j,end]互为翻转。除去翻转后缀后其余部分[0,j-1]能够形成回文的单词palindPrefixWord一定能与curWord构成

curWord[0,end]+palindPrefixWord[0,j-1]+palindPrefixWord[j,end]

的回文串(j-1=0时为空回文子串,字典中恰有两个单词互为翻转)。

2.哈希表

哈希表法思路比较简单清晰但也比较慢,第一轮遍历将所有字符串及其位置存入哈希表中,第二轮遍历依次截取字符串进行检验。有以下几种情况:

1.如果words里有空串,则配合当前字符串可以组成回文对。

2.如果当前串的翻转串也在words中(与本身不同),则可以组成回文对。

3.如果将字符串分割后有一半是回文串,且另一半的翻转在数组中,则可以组成回文对。


传送门:回文对

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.

给定一组唯一的单词, 找出所有不同 的索引对(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"]


import java.util.*;

/**
 *
 * 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.
 * 给定一组唯一的单词, 找出所有不同 的索引对(i, j),使得列表中的两个单词, words[i] + words[j] ,可拼接成回文串。
 *
 */

public class PalindromePairs {
   

    //字典树
    public List<List<Integer>> palindromePairs(String[] words) {
   
        List<List<Integer>> result = new ArrayList<>();
        TrieNode root = new TrieNode();
        for(int i = 0; i < words.length; i++){
   
            addWord(root, words[i], i);
        }
        for(int i = 0; i < words.length; i++){
   
            search(words, i, root, result);
        }
        return result;
    }

    private class TrieNode{
   
        TrieNode[] children;
        int reverseWordIdx;
        List<Integer> palindPrefixWords;
        
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值