前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >回文对

回文对

作者头像
你的益达
发布2020-08-10 10:00:54
3960
发布2020-08-10 10:00:54
举报

问题描述

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-pairs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解决方案

一种直观的方案为对于word1从前往后遍历,对于word2从后往前遍历进行匹配,若中间出现一个位置匹配不上,则说明word1+word2无法构成回文串。匹配过程中两者中如果有某个单词用光了,则判断还有剩余部分的那个单词其后的字符串能否构成回文串,例如:

word1 = “accbc”     word2 = "ca"

上述为word2用完了,word1剩余的情况,之后判断word1中的“cbc”能否构成回文;

word1 = “ad”     word2 = "bbada"

上述为word1用完了,word2剩余的情况,之后判断word2中的“bba”能否构成回文。

匹配过程中若两个单词都用光了,则word1+word2一定能构成回文串,不过需要注意的是word1不能等于word2(题目提到时唯一的一组单词,即不会出现重复单词)。

该问题很容易想到用前缀树来求解,首先将反转后的单词统统插入到前缀树中,然后遍历这组单词,以当前单词(记做word1)为前缀进行查找能够匹配的那些单词,如上述分析,查找中若出现word1没用完,当前缀树中某个单词用完,此时需要判断word1其后面的部分能否构成回文串,查找中若word1用完了,则以当前的结点开始做dfs,找到所有前缀为word1的单词,再判断其前面的部分能够构成回文。

最后还需要注意的是对于空字符串,其可以和任意一个回文串构成回文串。

class Solution {
    public static class Node{
        // 中间结点值均为-1,结尾结点值为该字符串的下标索引
        int index;
        Node[] next;
        public Node(){
            this.index = -1;
            this.next = new Node[26];
        }
    }
    // 插入逆置后的单词
    public void insertWord(String str, int index){
        Node node = root;
        for(int i = str.length() - 1; i >= 0; i--){
            char cur = str.charAt(i);
            if(node.next[cur - 'a'] == null){
                node.next[cur - 'a'] = new Node();
            }
            node = node.next[cur - 'a'];
            if(i == 0){
                node.index = index;
            }
        }
    }
    // 将回文对存入result中
    public void find(String perfix,int index, List<List<Integer>> result){
        List<Integer> list = new ArrayList<>();
        Node node = root;
        for(int i = 0; i < perfix.length(); i++){
            char cur = perfix.charAt(i);
            if(node.next[cur - 'a'] == null){
                return;
            }
            node = node.next[cur - 'a'];
            // word1比word2长的情况
            if(i != perfix.length() - 1 && node.index != -1){
                if(isPalin(perfix, i + 1, perfix.length() - 1)){
                    List<Integer> temp = new ArrayList<>(2);
                    temp.add(index);
                    temp.add(node.index);
                    result.add(temp);
                }
            }
        }
        // word1比word2短或等于的情况
        dfs(node, result, index);
    }
    public void dfs(Node node, List<List<Integer>> result, int index){
        if(node.index != -1 && node.index != index){
            if(isPalin(words[node.index], 0, words[node.index].length() - words[index].length() - 1)){
                List<Integer> temp = new ArrayList<>(2);
                temp.add(index);
                temp.add(node.index);
                result.add(temp);
            }
        }
        for(Node temp : node.next){
            if(temp == null){
                continue;
            }
            dfs(temp, result, index);
        }
    }
    public boolean isPalin(String str, int left, int right){
        while(left < right){
            if(str.charAt(left++) != str.charAt(right--)){
                return false;
            }
        }
        return true;
    }

    Node root = new Node();
    String[] words = null;
    public List<List<Integer>> palindromePairs(String[] words) {
        List<List<Integer>> result = new ArrayList<>();
        this.words = words; 
        for(int i = 0; i < words.length; i++){
            insertWord(words[i], i);
        }
        int nullIndex = -1;
        for(int i = 0; i < words.length; i++){
            if(words[i].length() == 0){
                nullIndex = i;
                continue;
            }
            find(words[i], i, result);
        }
        if(nullIndex != -1){
            for(int j = 0; j < words.length; j++){
                if(j == nullIndex){
                    continue;
                }
                if(isPalin(words[j], 0, words[j].length() - 1)){
                    List<Integer> temp1 = new ArrayList<>(2);
                    List<Integer> temp2 = new ArrayList<>(2);
                    temp1.add(nullIndex);
                    temp1.add(j);
                    temp2.add(j);
                    temp2.add(nullIndex);
                    result.add(temp1);
                    result.add(temp2);
                }
            }
        }
        return result;

    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-08-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题描述
  • 解决方案
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档