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;