Skip to content

Commit 6bcc91f

Browse files
committed
Add solutions related to Trie
1 parent fce58a1 commit 6bcc91f

File tree

11 files changed

+570
-125
lines changed

11 files changed

+570
-125
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package org.sean.stack;
2+
3+
import java.util.LinkedList;
4+
import java.util.Queue;
5+
6+
/***
7+
* 225. Implement Stack using Queues
8+
*/
9+
class MyStack {
10+
11+
private final Queue<Integer> queue;
12+
private final Queue<Integer> queueBackup;
13+
14+
private boolean mainQueueUsed;
15+
16+
public MyStack() {
17+
queue = new LinkedList<>();
18+
queueBackup = new LinkedList<>();
19+
mainQueueUsed = true;
20+
}
21+
22+
public void push(int x) {
23+
if (mainQueueUsed)
24+
queue.offer(x);
25+
else
26+
queueBackup.offer(x);
27+
}
28+
29+
public int pop() {
30+
return checkTopElem(true);
31+
}
32+
33+
private int checkTopElem(boolean needPop) {
34+
if (mainQueueUsed) {
35+
mainQueueUsed = !mainQueueUsed;
36+
while (!queue.isEmpty()) {
37+
int elem = queue.poll();
38+
if (queue.isEmpty()) {
39+
if (needPop)
40+
return elem;
41+
else {
42+
queueBackup.offer(elem);
43+
return elem;
44+
}
45+
} else {
46+
queueBackup.offer(elem);
47+
}
48+
}
49+
} else {
50+
mainQueueUsed = !mainQueueUsed;
51+
while (!queueBackup.isEmpty()) {
52+
int elem = queueBackup.poll();
53+
if (queueBackup.isEmpty()) {
54+
if (needPop)
55+
return elem;
56+
else {
57+
queue.offer(elem);
58+
return elem;
59+
}
60+
} else
61+
queue.offer(elem);
62+
}
63+
}
64+
throw new IllegalStateException("");
65+
}
66+
67+
public int top() {
68+
return checkTopElem(false);
69+
}
70+
71+
public boolean empty() {
72+
return queue.isEmpty() && queueBackup.isEmpty();
73+
}
74+
}
75+
76+
/**
77+
* Your MyStack object will be instantiated and called as such:
78+
* MyStack obj = new MyStack();
79+
* obj.push(x);
80+
* int param_2 = obj.pop();
81+
* int param_3 = obj.top();
82+
* boolean param_4 = obj.empty();
83+
*/

src/main/java/org/sean/tree/HuffmanCodec.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package org.sean.tree;
22

3-
import org.sean.trie.Trie;
3+
import org.sean.trie.TrieEx;
44

55
import java.util.*;
66
import java.util.stream.Collectors;
@@ -41,7 +41,7 @@ public String toString() {
4141
private final Map<String, Character> decodecMap = new HashMap<>();
4242
private Node root = null;
4343

44-
private Trie trie;
44+
private TrieEx trieEx;
4545

4646
private void buildTree(String raw) {
4747
pq.clear();
@@ -139,15 +139,15 @@ private void printTreeByLevel(Node root) {
139139

140140

141141
private void buildTrie() {
142-
trie = new Trie();
142+
trieEx = new TrieEx();
143143

144144
for (String code : decodecMap.keySet()) {
145-
trie.addWord(code);
145+
trieEx.addWord(code);
146146
}
147147
}
148148

149149
private boolean encodedStrFound(String encoded) {
150-
return trie.search(encoded);
150+
return trieEx.search(encoded);
151151
}
152152

153153
private void buildCodecMap(Set<Character> chars) {

src/main/java/org/sean/trie/CardIssuer.java

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,18 @@
2222
//
2323
public class CardIssuer {
2424
// region solution 2 : Using Trie to retrieve the prefix efficiently
25-
private Trie trie;
25+
private TrieEx trieEx;
2626

2727
Map<String, String> prefixCard = new HashMap<>();
2828
Map<String, List<Integer>> cardLengths = new HashMap<>();
2929

3030
private void init() {
31-
trie = new Trie();
31+
trieEx = new TrieEx();
3232

33-
trie.addWord("34");
34-
trie.addWord("37");
35-
trie.addWord("38");
36-
trie.addWord("39");
33+
trieEx.addWord("34");
34+
trieEx.addWord("37");
35+
trieEx.addWord("38");
36+
trieEx.addWord("39");
3737
String[] strAmex = {"34", "37"};
3838
String[] strDiners = {"38", "39"};
3939

@@ -42,35 +42,35 @@ private void init() {
4242
Arrays.stream(strAmex).forEach(s -> prefixCard.put(s, "Amex"));
4343
Arrays.stream(strDiners).forEach(s -> prefixCard.put(s, "Diners"));
4444

45-
trie.addWord("4");
45+
trieEx.addWord("4");
4646
prefixCard.put("4", "Visa");
4747
cardLengths.put("Visa", Arrays.asList(13, 16, 19));
4848

4949
for (int i = 51; i < 56; i++) {
5050
String s = String.valueOf(i);
51-
trie.addWord(s);
51+
trieEx.addWord(s);
5252
prefixCard.put(s, "MasterCard");
5353
}
5454
cardLengths.put("MasterCard", Arrays.asList(16));
5555

56-
trie.addWord("6011");
56+
trieEx.addWord("6011");
5757
prefixCard.put("6011", "Discover");
5858
for (int j = 622126; j <= 622925; j++) {
59-
trie.addWord(String.valueOf(j));
59+
trieEx.addWord(String.valueOf(j));
6060
prefixCard.put(String.valueOf(j), "Discover");
6161
}
6262
for (int k = 644; k < 650; k++) {
63-
trie.addWord(String.valueOf(k));
63+
trieEx.addWord(String.valueOf(k));
6464
prefixCard.put(String.valueOf(k), "Discover");
6565
}
66-
trie.addWord("65");
66+
trieEx.addWord("65");
6767
prefixCard.put("65", "Discover");
6868
cardLengths.put("Discover", Arrays.asList(16, 19));
6969

70-
trie.addWord("50");
70+
trieEx.addWord("50");
7171
prefixCard.put("50", "Maestro");
7272
for (int i = 56; i <= 69; i++) {
73-
trie.addWord(String.valueOf(i));
73+
trieEx.addWord(String.valueOf(i));
7474
prefixCard.put(String.valueOf(i), "Maestro");
7575
}
7676
cardLengths.put("Maestro", Arrays.asList(12, 13, 14, 15, 16, 17, 18, 19));
@@ -83,7 +83,7 @@ public String detectNetwork(String cardNumber) {
8383

8484
StringBuilder builder = new StringBuilder();
8585
List<String> matchedPrefixes = new ArrayList<>();
86-
trie.lookupPrefix(builder, matchedPrefixes, cardNumber, 0);
86+
trieEx.lookupPrefix(builder, matchedPrefixes, cardNumber, 0);
8787
if (matchedPrefixes.isEmpty()) return null;
8888

8989
String longestPrefix = builder.toString();
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package org.sean.trie;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
/***
7+
* 1268. Search Suggestions System
8+
*/
9+
public class SearchHelper {
10+
private Trie trie;
11+
12+
public List<List<String>> suggestedProducts(String[] products, String searchWord) {
13+
// Trie + DFS
14+
trie = new Trie();
15+
16+
for (String prod : products) {
17+
trie.insert(prod);
18+
}
19+
20+
ArrayList<List<String>> out = new ArrayList<>();
21+
for (int i = 0; i < searchWord.length(); i++) {
22+
out.add(new ArrayList<>());
23+
}
24+
lookupWords(trie, searchWord, 3, 0, out);
25+
26+
return out;
27+
}
28+
29+
private void lookupWords(Trie node, String prefix, int limit, int pos, List<List<String>> out) {
30+
if (pos >= prefix.length())
31+
return;
32+
33+
char ch = prefix.charAt(pos);
34+
//Trie node = this;
35+
Trie next = node.children[ch - 'a'];
36+
37+
List<String> candidatesPerPos = new ArrayList<>();
38+
if (next != null) {
39+
StringBuilder builder = new StringBuilder(prefix.substring(0, pos + 1));
40+
addWordsWithPrefix(next, builder, limit, candidatesPerPos);
41+
42+
out.get(pos).addAll(candidatesPerPos);
43+
44+
lookupWords(next, prefix, limit, pos + 1, out);
45+
}
46+
// else : break from here since no matched word found
47+
}
48+
49+
private void addWordsWithPrefix(Trie trie, StringBuilder prev, int limit, List<String> outWords) {
50+
if (outWords.size() >= limit)
51+
return;
52+
53+
if (trie.isEndOfWord()) {
54+
outWords.add(prev.toString());
55+
56+
// check for deeper words
57+
if (trie.children.length == 0)
58+
return;
59+
}
60+
61+
for (Trie t : trie.children) {
62+
if (t != null) {
63+
prev.append(t.getVal());
64+
int addedPos = prev.length() - 1;
65+
addWordsWithPrefix(t, prev, limit, outWords);
66+
prev.deleteCharAt(addedPos);
67+
68+
if (outWords.size() >= limit)
69+
break;
70+
}
71+
}
72+
}
73+
}

0 commit comments

Comments
 (0)