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”]
Java Solution
public List<List<Integer>> palindromePairs(String[] words) { List<List<Integer>> result = new ArrayList<>(); if(words == null || words.length < 2){ return result; } HashMap<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 s = words[i]; for(int k=0; k<=s.length(); k++){ String left = s.substring(0, k); String right= s.substring(k); //if left part is palindrome, find reversed right part if(isPalindrome(left)){ String reversedRight = new StringBuilder(right).reverse().toString(); if(map.containsKey(reversedRight) && map.get(reversedRight) != i){ ArrayList<Integer> l = new ArrayList<>(); l.add(map.get(reversedRight)); l.add(i); result.add(l); } } //if right part is a palindrome, find reversed left part if(isPalindrome(right)){ String reversedLeft = new StringBuilder(left).reverse().toString(); if(map.containsKey(reversedLeft) && map.get(reversedLeft) != i && right.length() != 0){ //make sure right is not "", already handled in the if above ArrayList<Integer> l = new ArrayList<>(); l.add(i); l.add(map.get(reversedLeft)); result.add(l); } } } } return result; } public boolean isPalindrome(String s){ int i=0; int j=s.length()-1; while(i<=j){ if(s.charAt(i)!=s.charAt(j)){ return false; } i++; j--; } return true; } |
Time complexity is O(n*k^2), where n is the number of words and k is the average length of each word.
Time: O(n^m)
Space: O(m)
n = nos of strings
m = max len of string
public static ArrayList<ArrayList> helperx(String[] strs) {
if (strs == null || strs.length < 2)
return null;
ArrayList<ArrayList> result = new ArrayList();
HashMap map = new HashMap();
for (int i = 0; i < strs.length; i++) {
String str = strs[i];
String rev = reverse(str);
if (map.containsKey(rev) || map.containsKey(rev.substring(0, rev.length() - 1))) {
ArrayList list1 = new ArrayList();
ArrayList list2 = new ArrayList();
if (map.containsKey(rev)) {
list1.add(i);
list1.add(map.get(rev));
list2.add(i);
list2.add(map.get(rev));
}
else{
list1.add(i);
list1.add(map.get(rev.substring(0, rev.length() - 1)));
list2.add(map.get(rev.substring(0, rev.length() - 1)));
list2.add(i);
}
result.add(list1);
result.add(list2);
} else {
map.put(str, i);
}
}
return result;
}
public static String reverse(String str) {
return str.length() > 0 ? str.substring(str.length()-1) + reverse(str.substring(0, str.length()-1)) : "";
}
public static List<List> PalindromePairs(String[] Words){
List<List> finalList = new ArrayList<List>();
for(int i=0; i<Words.length; i++){
for(int j=i+1; j<Words.length; j++){
String s1 = Words[i].concat(Words[j]);
String s2 = Words[j].concat(Words[i]);
String sRev1 = new StringBuilder(s1).reverse().toString();
String sRev2 = new StringBuilder(s2).reverse().toString();
if(s1.equals(sRev1)){
List list = new ArrayList();
list.add(Arrays.asList(Words).indexOf(Words[i]));
list.add(Arrays.asList(Words).indexOf(Words[j]));
finalList.add(list);
}
if(s2.equals(sRev2)){
List list = new ArrayList();
list.add(Arrays.asList(Words).indexOf(Words[j]));
list.add(Arrays.asList(Words).indexOf(Words[i]));
finalList.add(list);
}
}
}
return finalList;
}
Java, easy to understand and much shorter solutions:
public static List<List> PalindromePairs(String[] Words){
List<List> finalList = new ArrayList<List>();
for(int i=0; i<Words.length; i++){
for(int j=i+1; j<Words.length; j++){
String s1 = Words[i].concat(Words[j]);
String s2 = Words[j].concat(Words[i]);
String sRev1 = new StringBuilder(s1).reverse().toString();
String sRev2 = new StringBuilder(s2).reverse().toString();
if(s1.equals(sRev1)){
List list = new ArrayList();
list.add(Arrays.asList(Words).indexOf(Words[i]));
list.add(Arrays.asList(Words).indexOf(Words[j]));
finalList.add(list);
}
if(s2.equals(sRev2)){
List list = new ArrayList();
list.add(Arrays.asList(Words).indexOf(Words[j]));
list.add(Arrays.asList(Words).indexOf(Words[i]));
finalList.add(list);
}
}
}
return finalList;
}