leetcode@ [336] Palindrome Pairs (HashMap)
https://leetcode.com/problems/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:
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"]
public class Solution { public static boolean isPalindrome(StringBuffer sb) { if(sb == null || sb.length() == 0) return true; int l = 0, r = sb.length()-1; while(l < r) { if(sb.charAt(l) != sb.charAt(r)) return false; ++l; --r; } return true; } public static void buildMappings(String[] words, HashMap<String, HashSet<String> > mapping) { for(int i=0; i<words.length; ++i) { StringBuffer sb = new StringBuffer(words[i]); HashSet<String> adj = new HashSet<String> (); for(int j=0; j<=sb.length(); ++j) { /** partition words[i] into two parts */ StringBuffer prefix = new StringBuffer(sb.substring(0, j)); StringBuffer suffix = new StringBuffer(sb.substring(j)); /** check whether or not the prefix of words[i] is palindrome */ /** if it does, then the prefix can be the rotated point, otherwise not*/ if(isPalindrome(prefix)) { /** adj stores the strings where suffix + words[i] is palindrome */ adj.add(suffix.reverse().toString()); } if(isPalindrome(suffix)) { /** adj stores the strings where words[i] + prefix is palindrome */ adj.add(prefix.reverse().toString()); } } /** add it to mapping */ mapping.put(sb.toString(), adj); } HashSet<String> hs = new HashSet<String> (); for(int i=0; i<words.length; ++i) { StringBuffer sb = new StringBuffer(words[i]); if(isPalindrome(sb)) { hs.add(sb.toString()); } } for(int i=0; i<words.length; ++i) { if(words[i].equals("")) { HashSet<String> adj = new HashSet<String> (); adj.addAll(hs); mapping.put(words[i], adj); } } } public List<List<Integer>> palindromePairs(String[] words) { HashSet<List<Integer> > hres = new HashSet<List<Integer> > (); List<List<Integer> > res = new ArrayList<List<Integer> > (); HashMap<String, HashSet<String> > mapping = new HashMap<String, HashSet<String> > (); buildMappings(words, mapping); HashMap<String, Integer> dict = new HashMap<String, Integer> (); for(int i=0; i<words.length; ++i) { dict.put(words[i], i); } Iterator iter = mapping.entrySet().iterator(); while(iter.hasNext()) { HashMap.Entry entry = (HashMap.Entry) iter.next(); String str = (String) entry.getKey(); int lpos = dict.get(str); //System.out.print(str + " ==> "); HashSet<String> hs = (HashSet<String>) entry.getValue(); Iterator<String> itc = hs.iterator(); while(itc.hasNext()) { String s = itc.next(); //System.out.print(s + " "); if(dict.containsKey(s)) { int rpos = dict.get(s); if(lpos != rpos) { StringBuffer sb1 = new StringBuffer(str).append(s); if(isPalindrome(sb1)) { List<Integer> ll = new ArrayList<Integer> (); ll.add(lpos); ll.add(rpos); hres.add(ll); } StringBuffer sb2 = new StringBuffer(s).append(str); if(isPalindrome(sb2)) { List<Integer> ll2 = new ArrayList<Integer> (); ll2.add(rpos); ll2.add(lpos); hres.add(ll2); } } } }//System.out.println(); } res.addAll(hres); return res; } }