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:
Given words = ["bat", "tab", "cat"]
Return [[0, 1], [1, 0]]
The palindromes are ["battab", "tabbat"]
Example 2:
Given words = ["abcd", "dcba", "lls", "s", "sssll"]
Return [[0, 1], [1, 0], [3, 2], [2, 4]]
The palindromes are ["dcbaabcd", "abcddcba", "slls", "llssssll"]
Credits:
Special thanks to @dietpepsi for adding this problem and creating all test cases.
The idea is for each of the word, find the strings that can be added before or after to form a palindrome, and generate the results.
For example "abcd"
before abcd we could add dcba to form dcbaabcd,
and add dcb to form dcbabcd.
after abcd we could add dcba to form abcddcba
and add cba to form abcdcba.
And we check whether dcba,dcb,dcba,cba is in the list, if there is a occurence we add (i,j) or (j,i) to the result.
But there would be duplicates if abcd and dcba all the in the list, because for after abcd we will find dcba, and for before dcba we will find abcd.
what we could do is in whether the getBefore or getAfter, we do not return the reverse of the string s to avoid the duplicates.
Code:
public class Solution {
public List<List<Integer>> palindromePairs(String[] words) {
List<List<Integer>> ret = new ArrayList<>();
HashMap<String,HashSet<Integer>> hm = new HashMap<>();
for(int i = 0; i < words.length; i++){
hm.computeIfAbsent(words[i], k->new HashSet<Integer>()).add(i);
}
for(int i = 0; i < words.length; i++){
String s = words[i];
List<String> before = getBefore(s);
List<String> after = getAfter(s);
for(String bf : before){
for(int j : hm.getOrDefault(bf,new HashSet<Integer>())){
List<Integer> temp = new ArrayList<>();
if(i == j) continue;
temp.add(j);
temp.add(i);
ret.add(temp);
}
}
for(String af : after){
for(int j : hm.getOrDefault(af,new HashSet<Integer>())){
List<Integer> temp = new ArrayList<>();
if(i == j) continue;
temp.add(i);
temp.add(j);
ret.add(temp);
}
}
}
return ret;
}
public List<String> getAfter(String s){
List<String> ret = new ArrayList<>();
String rev = new StringBuilder(s).reverse().toString();
for(int i = 0; i <= s.length(); i++){
if(rev.substring(0,i).equals(s.substring(s.length() - i,s.length()))){
ret.add(rev.substring(i,s.length()));
}
}
return ret;
}
public List<String> getBefore(String s){
List<String> ret = new ArrayList<>();
String rev = new StringBuilder(s).reverse().toString();
for(int i = 1; i <= s.length(); i++){ // i start from 1 to avoid duplicates
if(s.substring(0,i).equals(rev.substring(s.length() - i,s.length()))){
ret.add(rev.substring(0,s.length() - i));
}
}
return ret;
}
}
本文介绍了一种寻找字符串数组中所有能组成回文串的唯一字符串对的方法。通过逆序匹配,该算法能够高效地找到所有符合条件的字符串组合。
481

被折叠的 条评论
为什么被折叠?



