Question
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"]
Answer
Brute-force的做法是两层for循环,遍历每个string,看有无string可以与之匹配为palindrome。
较好的做法是利用HashMap。
对于String a来说,考虑两种情况:
1. a为空,则a与集合中任意已经对称的string可以组成结果
2. a不为空。
则有三种情况:
a. reverse(a)在集合中
b. a[0..i]对称,且reverse(a[i + 1,...,n])在集合中。如"aaabc", "cba"
c. a[i,..,n]对称,且reverse(a[0,...,i])在集合中。如"abcc", "ba"
1 public class Solution { 2 public List<List<Integer>> palindromePairs(String[] words) { 3 List<List<Integer>> result = new ArrayList<>(); 4 if (words == null || words.length == 0) { 5 return result; 6 } 7 // Record each string position 8 Map<String, Integer> map = new HashMap<>(); 9 Set<Integer> palindromeSet = new HashSet<>(); 10 int len = words.length; 11 for (int i = 0; i < len; i++) { 12 map.put(words[i], i); 13 if (isPalindrome(words[i])) { 14 palindromeSet.add(i); 15 } 16 } 17 // Traverse 18 for (int i = 0; i < len; i++) { 19 String word = words[i]; 20 if (word.length() == 0) { 21 for (int index : palindromeSet) { 22 addResult(result, i, index); 23 } 24 } 25 int l = word.length(); 26 for (int j = 0; j < l; j++) { 27 String front = word.substring(0, j); 28 String back = word.substring(j, l); 29 String rFront = reverse(front); 30 String rBack = reverse(back); 31 if (isPalindrome(front) && map.containsKey(rBack)) { 32 addResult(result, map.get(rBack), i); 33 } 34 if (isPalindrome(back) && map.containsKey(rFront)) { 35 addResult(result, i, map.get(rFront)); 36 } 37 } 38 } 39 return result; 40 } 41 42 private String reverse(String s) { 43 StringBuilder sb = new StringBuilder(s); 44 return sb.reverse().toString(); 45 } 46 47 private void addResult(List<List<Integer>> result, int start, int end) { 48 if (start == end) { 49 return; 50 } 51 List<Integer> indexes = new ArrayList<>(); 52 indexes.add(start); 53 indexes.add(end); 54 result.add(indexes); 55 } 56 57 private boolean isPalindrome(String s) { 58 int i = 0; 59 int j = s.length() - 1; 60 while (i < j) { 61 if (s.charAt(i) != s.charAt(j)) { 62 return false; 63 } 64 i++; 65 j--; 66 } 67 return true; 68 } 69 }