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
str1
is Palindrome, then we reversestr2
, and check if the map containsKeyreversedStr2
. If it contains, then we can concate StringreversedStr2
andstr1
to get the palindrome string. Note: thereversedStr2
should be on the left andstr1
on the right. - if
str2
is Palindrome, then we reversestr1
, and check if the map containsKeyreversedStr1
. If it contains, then we can concate Stringstr2
andreversedStr1
to get the palindrome string. Note: thestr2
should be on the left andreversedStr1
on 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;
}