Skip to main content

Palindrome Pairs Solution

Problem Description​

Given a list of unique words, find all pairs of distinct indices (i, j) in the list such that the concatenation of words[i] + words[j] forms a palindrome.

Examples​

Example 1:

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

Example 2:

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

Constraints​

  • 1<=words.length<=50001 <= words.length <= 5000
  • 0<=words[i].length<=3000 <= words[i].length <= 300
  • words[i] consists of lowercase English letters.

Solution for Palindrome Pairs Problem​

Intuition And Approach​

To efficiently find all palindrome pairs in the list of words, we can leverage a HashMap (or Trie for optimization) to store the reverse of each word along with its index. Then, for each word, we check its substrings to find potential pairs that form palindromes.

Code in Different Languages​

Written by @mahek0620
 
import java.util.*;

class Solution {
public List<List<Integer>> palindromePairs(String[] words) {
Map<String, Integer> wordMap = new HashMap<>();
List<List<Integer>> result = new ArrayList<>();

// Build the word map
for (int i = 0; i < words.length; i++) {
wordMap.put(words[i], i);
}

// Iterate through each word
for (int i = 0; i < words.length; i++) {
String word = words[i];
int n = word.length();

// Check each possible split of the word into left and right parts
for (int j = 0; j <= n; j++) {
String left = word.substring(0, j);
String right = word.substring(j);
String revLeft = new StringBuilder(left).reverse().toString();
String revRight = new StringBuilder(right).reverse().toString();

// Check if left + right forms a palindrome
if (isPalindrome(left) && wordMap.containsKey(revRight) && wordMap.get(revRight) != i) {
result.add(Arrays.asList(wordMap.get(revRight), i));
}

// Check if right + left forms a palindrome (to avoid duplicates)
if (j < n && isPalindrome(right) && wordMap.containsKey(revLeft) && wordMap.get(revLeft) != i) {
result.add(Arrays.asList(i, wordMap.get(revLeft)));
}
}
}

return result;
}

private boolean isPalindrome(String s) {
int left = 0, right = s.length() - 1;
while (left < right) {
if (s.charAt(left) != s.charAt(right)) {
return false;
}
left++;
right--;
}
return true;
}
}

References​