Skip to content

Commit 961a315

Browse files
committed
[Function add]
1. Add leetcode trie tree questions.
1 parent 6ac9f64 commit 961a315

7 files changed

+596
-0
lines changed

README.md

+14
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,20 @@
496496
[315. Count of Smaller Numbers After Self](https://github.com/Seanforfun/Algorithm-and-Leetcode/blob/master/leetcode/315.%20Count%20of%20Smaller%20Numbers%20After%20Self.md)
497497

498498

499+
## LeetCode by Tag:
500+
1. [Tag table from huahua](https://docs.google.com/spreadsheets/d/1SbpY-04Cz8EWw3A_LBUmDEXKUMO31DBjfeMoA0dlfIA/edit#gid=126913158)
501+
502+
### Advance
503+
#### [Trie Tree]()
504+
* [208. Implement Trie (Prefix Tree)](https://github.com/Seanforfun/Algorithm-and-Leetcode/blob/master/leetcode/208.%20Implement%20Trie%20(Prefix%20Tree).md)
505+
* [648. Replace Words](https://github.com/Seanforfun/Algorithm-and-Leetcode/blob/master/leetcode/648.%20Replace%20Words.md)
506+
* [676. Implement Magic Dictionary](https://github.com/Seanforfun/Algorithm-and-Leetcode/blob/master/leetcode/676.%20Implement%20Magic%20Dictionary.md)
507+
* [677. Map Sum Pairs](https://github.com/Seanforfun/Algorithm-and-Leetcode/blob/master/leetcode/677.%20Map%20Sum%20Pairs.md)
508+
* [720. Longest Word in Dictionary](https://github.com/Seanforfun/Algorithm-and-Leetcode/blob/master/leetcode/720.%20Longest%20Word%20in%20Dictionary.md)
509+
* [745. Prefix and Suffix Search](https://github.com/Seanforfun/Algorithm-and-Leetcode/blob/master/leetcode/745.%20Prefix%20and%20Suffix%20Search.md)
510+
* Conclusion: [Data structure | Trie Tree 字典树](https://seanforfun.github.io/datastructure/2018/11/07/TrieTree.html)
511+
512+
499513
## Algorithm(4th_Edition)
500514
Reading notes of book Algorithm(4th Algorithm),ISBN: 9787115293800.
501515
All java realization codes are placed in different packages.

leetcode/208. Implement Trie (Prefix Tree).md

+68
Original file line numberDiff line numberDiff line change
@@ -150,5 +150,73 @@ class Trie {
150150
*/
151151
```
152152

153+
### Third time
154+
```Java
155+
class Trie {
156+
private static class Node{
157+
boolean isLeaf;
158+
Node[] childs;
159+
public Node(){
160+
this.childs = new Node[26];
161+
}
162+
}
163+
private Node root;
164+
/** Initialize your data structure here. */
165+
public Trie() {
166+
this.root = new Node();
167+
}
168+
169+
/** Inserts a word into the trie. */
170+
public void insert(String word) {
171+
char[] arr = word.toCharArray();
172+
Node node = root;
173+
for(int i = 0; i < arr.length; i++){
174+
int c = arr[i] - 'a';
175+
if(node.childs[c] == null){
176+
node.childs[c] = new Node();
177+
}
178+
node = node.childs[c];
179+
}
180+
node.isLeaf = true;
181+
}
182+
183+
/** Returns if the word is in the trie. */
184+
public boolean search(String word) {
185+
char[] arr = word.toCharArray();
186+
Node node = root;
187+
for(int i = 0; i < arr.length; i++){
188+
int c = arr[i] - 'a';
189+
if(node.childs[c] == null){
190+
return false;
191+
}
192+
node = node.childs[c];
193+
}
194+
return node.isLeaf;
195+
}
196+
197+
/** Returns if there is any word in the trie that starts with the given prefix. */
198+
public boolean startsWith(String prefix) {
199+
char[] arr = prefix.toCharArray();
200+
Node node = root;
201+
for(int i = 0; i < arr.length; i++){
202+
int c = arr[i] - 'a';
203+
if(node.childs[c] == null){
204+
return false;
205+
}
206+
node = node.childs[c];
207+
}
208+
return true;
209+
}
210+
}
211+
212+
/**
213+
* Your Trie object will be instantiated and called as such:
214+
* Trie obj = new Trie();
215+
* obj.insert(word);
216+
* boolean param_2 = obj.search(word);
217+
* boolean param_3 = obj.startsWith(prefix);
218+
*/
219+
```
220+
153221
### Reference
154222
1. [Trie Tree 字典树](https://seanforfun.github.io/datastructure/2018/11/07/TrieTree.html)

leetcode/648. Replace Words.md

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
## 648. Replace Words
2+
3+
### Question
4+
In English, we have a concept called root, which can be followed by some other words to form another longer word - let's call this word successor. For example, the root an, followed by other, which can form another word another.
5+
6+
Now, given a dictionary consisting of many roots and a sentence. You need to replace all the successor in the sentence with the root forming it. If a successor has many roots can form it, replace it with the root with the shortest length.
7+
8+
You need to output the sentence after the replacement.
9+
10+
```
11+
Example 1:
12+
13+
Input: dict = ["cat", "bat", "rat"]
14+
sentence = "the cattle was rattled by the battery"
15+
Output: "the cat was rat by the bat"
16+
```
17+
18+
Note:
19+
* The input will only have lower-case letters.
20+
* 1 <= dict words number <= 1000
21+
* 1 <= sentence words number <= 1000
22+
* 1 <= root length <= 100
23+
* 1 <= sentence words length <= 1000
24+
25+
26+
### Thinking:
27+
* Method 1:Trie Tree
28+
29+
```Java
30+
class Solution {
31+
private static class TrieTree{
32+
public static class Node{
33+
boolean isLeaf;
34+
Node[] childs;
35+
public Node(){
36+
this.childs = new Node[26];
37+
}
38+
}
39+
private Node root;
40+
public TrieTree(){
41+
this.root = new Node();
42+
}
43+
public void insert(String s){
44+
char[] arr = s.toCharArray();
45+
Node node = root;
46+
for(int i = 0; i < arr.length; i++){
47+
if(node.isLeaf) return;
48+
int c = arr[i] - 'a';
49+
if(node.childs[c] == null){
50+
node.childs[c] = new Node();
51+
}
52+
node = node.childs[c];
53+
}
54+
node.isLeaf = true;
55+
}
56+
public String findClosest(String s){
57+
char[] arr = s.toCharArray();
58+
Node node = root;
59+
for(int i = 0; i < arr.length; i++){
60+
int c = arr[i] - 'a';
61+
if(node.childs[c] == null){
62+
return s;
63+
}else{
64+
node = node.childs[c];
65+
if(node.isLeaf){
66+
return s.substring(0, i + 1);
67+
}
68+
}
69+
}
70+
return s;
71+
}
72+
}
73+
public String replaceWords(List<String> dict, String sentence) {
74+
if(sentence == null || sentence.length() == 0) return "";
75+
if(dict == null || dict.size() == 0) return sentence;
76+
TrieTree tree = new TrieTree();
77+
for(String s : dict){
78+
tree.insert(s);
79+
}
80+
StringBuilder sb = new StringBuilder();
81+
String[] tokens = sentence.split(" ");
82+
for(String token : tokens){
83+
sb.append(" " + tree.findClosest(token));
84+
}
85+
return sb.toString().substring(1);
86+
}
87+
}
88+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
## 676. Implement Magic Dictionary
2+
3+
### Question
4+
Implement a magic directory with buildDict, and search methods.
5+
6+
For the method buildDict, you'll be given a list of non-repetitive words to build a dictionary.
7+
8+
For the method search, you'll be given a word, and judge whether if you modify exactly one character into another character in this word, the modified word is in the dictionary you just built.
9+
10+
```
11+
Example 1:
12+
13+
Input: buildDict(["hello", "leetcode"]), Output: Null
14+
Input: search("hello"), Output: False
15+
Input: search("hhllo"), Output: True
16+
Input: search("hell"), Output: False
17+
Input: search("leetcoded"), Output: False
18+
```
19+
20+
Note:
21+
1. You may assume that all the inputs are consist of lowercase letters a-z.
22+
2. For contest purpose, the test data is rather small by now. You could think about highly efficient algorithm after the contest.
23+
3. Please remember to RESET your class variables declared in class MagicDictionary, as static/class variables are persisted across multiple test cases. Please see here for more details.
24+
25+
### Solution
26+
* Method 1: Trie Tree
27+
28+
```Java
29+
class MagicDictionary {
30+
private static class Node{
31+
boolean isLeaf;
32+
Node[] childs;
33+
public Node(){
34+
this.childs = new Node[26];
35+
}
36+
}
37+
private Node root;
38+
/** Initialize your data structure here. */
39+
public MagicDictionary() {
40+
this.root = new Node();
41+
}
42+
43+
/** Build a dictionary through a list of words */
44+
public void buildDict(String[] dict) {
45+
for(String s : dict){
46+
char[] arr = s.toCharArray();
47+
Node node = root;
48+
for(int i = 0; i < arr.length; i++){
49+
int c = arr[i] - 'a';
50+
if(node.childs[c] == null){
51+
node.childs[c] = new Node();
52+
}
53+
node = node.childs[c];
54+
}
55+
node.isLeaf = true;
56+
}
57+
}
58+
/** Returns if there is any word in the trie that equals to the given word after modifying exactly one character */
59+
public boolean search(String word) {
60+
if(word == null || word.length() == 0) return false;
61+
return dfs(word, 0, root, 0);
62+
}
63+
private boolean dfs(String word, int index, Node node, int diff){
64+
if(diff > 1) return false;
65+
if(index == word.length()){
66+
if(diff == 1 && node.isLeaf){
67+
return true;
68+
}else{
69+
return false;
70+
}
71+
}
72+
int c = word.charAt(index) - 'a';
73+
boolean res = false;
74+
for(int i = 0; i < 26; i++){
75+
if(node.childs[i] != null){
76+
res |= dfs(word, index + 1, node.childs[i], diff + (c == i ? 0: 1));
77+
}
78+
}
79+
return res;
80+
}
81+
}
82+
83+
/**
84+
* Your MagicDictionary object will be instantiated and called as such:
85+
* MagicDictionary obj = new MagicDictionary();
86+
* obj.buildDict(dict);
87+
* boolean param_2 = obj.search(word);
88+
*/
89+
```

leetcode/677. Map Sum Pairs.md

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
## 677. Map Sum Pairs
2+
3+
### Question:
4+
Implement a MapSum class with insert, and sum methods.
5+
6+
For the method insert, you'll be given a pair of (string, integer). The string represents the key and the integer represents the value. If the key already existed, then the original key-value pair will be overridden to the new one.
7+
8+
For the method sum, you'll be given a string representing the prefix, and you need to return the sum of all the pairs' value whose key starts with the prefix.
9+
10+
```
11+
Example 1:
12+
13+
Input: insert("apple", 3), Output: Null
14+
Input: sum("ap"), Output: 3
15+
Input: insert("app", 2), Output: Null
16+
Input: sum("ap"), Output: 5
17+
```
18+
19+
### Solution
20+
* Method 1: Trie Tree
21+
22+
```Java
23+
class MapSum {
24+
25+
private static class Node{
26+
int count;
27+
Node[] childs;
28+
boolean isLeaf;
29+
public Node(){
30+
this.childs = new Node[26];
31+
}
32+
}
33+
private Node root;
34+
/** Initialize your data structure here. */
35+
public MapSum() {
36+
this.root = new Node();
37+
}
38+
39+
public void insert(String key, int val) {
40+
char[] arr = key.toCharArray();
41+
Node node = root;
42+
for(int i = 0; i < arr.length; i++){
43+
int c = arr[i] - 'a';
44+
if(node.childs[c] == null){
45+
node.childs[c] = new Node();
46+
}
47+
node = node.childs[c];
48+
}
49+
node.isLeaf = true;
50+
node.count = val;
51+
}
52+
53+
public int sum(String prefix) {
54+
char[] arr = prefix.toCharArray();
55+
Node node = root;
56+
for(int i = 0; i < arr.length; i++){
57+
int c = arr[i] - 'a';
58+
if(node.childs[c] == null){
59+
return 0;
60+
}else{
61+
node = node.childs[c];
62+
}
63+
}
64+
return childsCount(node);
65+
}
66+
private int childsCount(Node node){
67+
int count = node.count;
68+
for(int i = 0; i < 26; i++){
69+
if(node.childs[i] != null){
70+
count += childsCount(node.childs[i]);
71+
}
72+
}
73+
return count;
74+
}
75+
}
76+
77+
/**
78+
* Your MapSum object will be instantiated and called as such:
79+
* MapSum obj = new MapSum();
80+
* obj.insert(key,val);
81+
* int param_2 = obj.sum(prefix);
82+
*/
83+
```

0 commit comments

Comments
 (0)