leetcode No336. Palindrome Pairs

Posted Dufre.WC

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode No336. Palindrome Pairs相关的知识,希望对你有一定的参考价值。

Question

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.

Example 1:

Input: ["abcd","dcba","lls","s","sssll"]
Output: [[0,1],[1,0],[3,2],[2,4]] 
Explanation: The palindromes are ["dcbaabcd","abcddcba","slls","llssssll"]

Example 2:

Input: ["bat","tab","cat"]
Output: [[0,1],[1,0]] 
Explanation: The palindromes are ["battab","tabbat"]

Algorithm

暴力法我就不说了,暴力法时间复杂度为O(n×n×k),k为单词的平均长度。

下面来具体分析,先来看字符串s1(长度为k1),字符串s2(长度为k2)组合在一起判断是否是一个回文串有哪几种情况?

  1. k1 = k2
  2. k1 < k2
    s2剩下的部分必须要满足回文
  3. k1 > k2
    s1剩下的部分必须要满足回文

思考两个问题?

  • 假设s1的首字符是a,怎么快速找到以a结尾的字符串?
    • 构建Trie,只不过要反着构建
  • 第2,3种情况,如何快速的知道剩下的部分是否是回文?
    • 第2种情况,已知s1,查找s2,s1先遍历完,因此在遍历到s2的节点b时,为了能快速判断剩下的部分是回文,只要记录从该节点向后所有剩余能构成回文的字符串的下标即可。
    • 第3种情况,已知s1,查找s2,s2先遍历完,只需要判断s1剩下的部分是回文即可。

因此,需要构建的前缀树的结构如下:

class TrieNode 
    public TrieNode[] children;
    public int index;  //题目要求返回下标,因为这里记录下标
    public List<Integer> suffixs;  //记录节点向后所有的剩余能构成回文的字符串下标
    
    public TrieNode()
        this.children = new TrieNode[26];
        this.index = -1;
        this.suffixs = new ArrayList<>();
    

一个简单示例:

  • 构建图示
  • 查找图示(以字符串"a"为例)

    完整代码如下:
  • 构建
    • 字符串取反;
    • 遍历word,创建节点;
    • word.substring(j+1)为回文,则添加到该节点的suffixs列表中;这里要注意word本身为回文则添加到root节点的suffixs列表中;
  • 查找
    • 遍历word;
    • 如果word.substring(j)为回文,则要看当前节点是否为一个单词,如果是,添加到结果中;(对应第三种情况,k1 > k2)
    • word遍历结束且有以word结尾的单词,则要看当前节点的suffixs列表;(对应第二种情况,k1 < k2)

Code

class Solution 
    private TrieNode root;
    public boolean isPalindrome(String s)
        int i=0, j=s.length()-1;
        while (i < j)
            if (s.charAt(i) != s.charAt(j))
                return false;
            
            i++;
            j--;
        

        return true;
    
    public List<List<Integer>> palindromePairs(String[] words) 
        this.root = new TrieNode();
        int n = words.length;

        //build TrieNode Tree
        for (int i=0; i<n; i++)
            String word = new StringBuilder(words[i]).reverse().toString();
            TrieNode cur = root;

            if (isPalindrome(word.substring(0)))
                cur.suffixs.add(i);
            for (int j=0; j<word.length(); j++)
                int index = word.charAt(j) - 'a';
                if (cur.children[index] == null)
                    cur.children[index] = new TrieNode();
                cur = cur.children[index];
                if (isPalindrome(word.substring(j+1)))
                    cur.suffixs.add(i);
            
            cur.index = i;
        

        //search 
        List<List<Integer>> res = new ArrayList<>();
        for (int i=0; i<n; i++)
            String word = words[i];
            TrieNode cur = root;

            int j=0;
            for (; j<word.length(); j++)
                if (isPalindrome(word.substring(j)) && cur.index!=-1)
                    res.add(Arrays.asList(i, cur.index));
                

                int index = word.charAt(j) - 'a';
                if (cur.children[index] == null)
                    break;
                cur = cur.children[index];
            

            if (j == word.length())
                for (int k : cur.suffixs)
                    if (k != i)
                        res.add(Arrays.asList(i, k));
                
            
        

        return res;
    


class TrieNode 
    public TrieNode[] children;
    public int index;
    public List<Integer> suffixs;
    
    public TrieNode()
        this.children = new TrieNode[26];
        this.index = -1;
        this.suffixs = new ArrayList<>();
    

时间复杂度:O(n×k×k),因为k在一定范围内,所以这个问题优化为一个线性问题。

更多算法总结请关注我的微信公众号《Coder101》

以上是关于leetcode No336. Palindrome Pairs的主要内容,如果未能解决你的问题,请参考以下文章

leetcode No336. Palindrome Pairs

LeetCode 336. Palindrome Pairs(回文对)

LeetCode笔记:Weekly Contest 336

[Leetcode] 336. Palindrome Pairs_Hard

leetcode336. Palindrome Pairs

LeetCodePalindrome Pairs(336)