LeetCode Q 336 - Palindrome Pairs
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”]
Solution
The idea is we first store each string and its index in the map.
Then, for each string, we divide it into two substrings(str1 and str2), and check all the substring pairs.
- if
str1is Palindrome, then we reversestr2, and check if the map containsKeyreversedStr2. If it contains, then we can concate StringreversedStr2andstr1to get the palindrome string. Note: thereversedStr2should be on the left andstr1on the right. - if
str2is Palindrome, then we reversestr1, and check if the map containsKeyreversedStr1. If it contains, then we can concate Stringstr2andreversedStr1to get the palindrome string. Note: thestr2should be on the left andreversedStr1on the right.
Caution: MUST CHECK whether str.length() is equal to 0 in either if statement, because we need to make sure we do not add duplicate pairs (if str1.length() == 0, both of str1 and str2 will from input array).
Code:
public List<List<Integer>> palindromePairs(String[] words) {
List<List<Integer>> res = new ArrayList<>();
if (words == null || words.length == 0)
return res;
Map<String, Integer> map = new HashMap<>();
for (int i = 0; i < words.length; i++)
map.put(words[i], i);
for (int i = 0; i < words.length; i++) {
String word = words[i];
for (int j = 0; j <= word.length(); j++) {
String str1 = word.substring(0, j);
String str2 = word.substring(j);
if (isPalindrome(str1)) {
String reversedStr2 = new StringBuilder(str2).reverse().toString();
if (map.containsKey(reversedStr2) && map.get(reversedStr2) != i && j != 0)
res.add(Arrays.asList(map.get(reversedStr2), str1));
}
if (isPalindrome(str2)) {
String reversedStr1 = new StringBuilder(str1).reverse().toString();
if (map.containsKey(reversedStr1) && map.get(reversedStr1) != i)
res.add(Arrays.asList(i,map.get(reversedStr1)));
}
}
}
return res;
}
private boolean isPalindrome(String str) {
int i = 0, j = str.length() - 1;
while (i < j) {
if (str.charAt(i++) != str.charAt(j--)) return false;
}
return true;
}