-
Notifications
You must be signed in to change notification settings - Fork 251
/
PalindromePairs.java
147 lines (123 loc) · 4.75 KB
/
PalindromePairs.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package palindrome_pairs;
import java.util.*;
import org.junit.*;
import static org.junit.Assert.*;
public class PalindromePairs {
/*
Palindrome Pairs - HashMap
AirBnB Interview Question
*/
public class Solution {
private boolean isPalindrome(String s) {
for (int i = 0; i < s.length() / 2; ++i)
if (s.charAt(i) != s.charAt(s.length() - 1 - i))
return false;
return true;
}
public List<List<Integer>> palindromePairs(String[] words) {
List<List<Integer>> res = new ArrayList<>();
if (words == null) return res;
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++) {
int left = 0, right = 0;
while (left <= right) {
String s = words[i].substring(left, right);
Integer j = map.get(new StringBuilder(s).reverse().toString());
if (j != null && i != j && isPalindrome(words[i].substring(left == 0 ? right : 0, left == 0 ? words[i].length() : left)))
res.add(Arrays.asList(left == 0 ? new Integer[]{i, j} : new Integer[]{j, i}));
if (right < words[i].length()) right++;
else left++;
}
}
return res;
}
}
/*
Palindrome Pairs - Trie
AirBnB Interview Question
*/
public class Solution_2 {
class TrieNode {
TrieNode[] next;
int index;
List<Integer> list;
TrieNode() {
next = new TrieNode[26];
index = -1;
list = new ArrayList<>();
}
}
private void addWord(TrieNode root, String word, int index) {
for (int i = word.length() - 1; i >= 0; i--) {
if (root.next[word.charAt(i) - 'a'] == null) {
root.next[word.charAt(i) - 'a'] = new TrieNode();
}
if (isPalindrome(word, 0, i)) {
root.list.add(index);
}
root = root.next[word.charAt(i) - 'a'];
}
root.list.add(index);
root.index = index;
}
private boolean isPalindrome(String word, int i, int j) {
while (i < j) {
if (word.charAt(i++) != word.charAt(j--)) return false;
}
return true;
}
private void search(String[] words, int i, TrieNode root, List<List<Integer>> list) {
for (int j = 0; j < words[i].length(); j++) {
if (root.index >= 0 && root.index != i && isPalindrome(words[i], j, words[i].length() - 1)) {
list.add(Arrays.asList(i, root.index));
}
root = root.next[words[i].charAt(j) - 'a'];
if (root == null) return;
}
for (int j : root.list) {
if (i == j) continue;
list.add(Arrays.asList(i, j));
}
}
public List<List<Integer>> palindromePairs(String[] words) {
List<List<Integer>> res = new ArrayList<>();
TrieNode root = new TrieNode();
for (int i = 0; i < words.length; i++) {
addWord(root, words[i], i);
}
for (int i = 0; i < words.length; i++) {
search(words, i, root, res);
}
return res;
}
}
public static class UnitTest {
@Test
public void test1() {
Solution sol = new PalindromePairs().new Solution();
String[] test = new String[]{"bat", "tab", "cat"};
List<List<Integer>> rslt = sol.palindromePairs(test);
assertEquals(2, rslt.size());
test = new String[]{"abcd", "dcba", "lls", "s", "sssll"};
rslt = sol.palindromePairs(test);
assertEquals(4, rslt.size());
test = new String[]{"a", ""};
rslt = sol.palindromePairs(test);
assertEquals(2, rslt.size());
}
@Test
public void test2() {
Solution_2 sol = new PalindromePairs().new Solution_2();
String[] test = new String[]{"bat", "tab", "cat"};
List<List<Integer>> rslt = sol.palindromePairs(test);
assertEquals(2, rslt.size());
test = new String[]{"abcd", "dcba", "lls", "s", "sssll"};
rslt = sol.palindromePairs(test);
assertEquals(4, rslt.size());
test = new String[]{"a", ""};
rslt = sol.palindromePairs(test);
assertEquals(2, rslt.size());
}
}
}