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:
Givenwords
= ["bat", "tab", "cat"]
Return [[0, 1], [1, 0]]
The palindromes are ["battab", "tabbat"]
Example 2:
Givenwords
= ["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
> palindromePairs(String[] words) { 3 List
> result = new ArrayList<>(); 4 if (words == null || words.length == 0) { 5 return result; 6 } 7 // Record each string position 8 Map map = new HashMap<>(); 9 Set 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 // Traverse18 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
> result, int start, int end) {48 if (start == end) {49 return;50 }51 List 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 }