Skip to content

Commit c12c012

Browse files
committed
modify code
1 parent c358e13 commit c12c012

File tree

3 files changed

+183
-186
lines changed

3 files changed

+183
-186
lines changed

src/class044/Code01_TrieTree.java

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package class044;
22

3+
import java.util.HashMap;
4+
35
// 用类描述实现前缀树,路径是数组结构
46
// 测试链接 : https://leetcode.cn/problems/implement-trie-ii-prefix-tree/
57
public class Code01_TrieTree {
68

7-
class Trie {
9+
// 路是数组实现的
10+
// 提交时把类名、构造方法改为Trie
11+
class Trie1 {
812

913
class TrieNode {
1014
public int pass;
@@ -20,7 +24,7 @@ public TrieNode() {
2024

2125
private TrieNode root;
2226

23-
public Trie() {
27+
public Trie1() {
2428
root = new TrieNode();
2529
}
2630

@@ -79,5 +83,85 @@ public int countWordsStartingWith(String pre) {
7983
}
8084

8185
}
86+
87+
// 路是数组实现的
88+
// 提交时把类名、构造方法改为Trie
89+
class Trie2 {
90+
91+
class TrieNode {
92+
public int pass;
93+
public int end;
94+
HashMap<Integer, TrieNode> nexts;
95+
96+
public TrieNode() {
97+
pass = 0;
98+
end = 0;
99+
nexts = new HashMap<>();
100+
}
101+
}
102+
103+
private TrieNode root;
104+
105+
public Trie2() {
106+
root = new TrieNode();
107+
}
108+
109+
public void insert(String word) {
110+
TrieNode node = root;
111+
node.pass++;
112+
for (int i = 0, path; i < word.length(); i++) { // 从左往右遍历字符
113+
path = word.charAt(i);
114+
if (!node.nexts.containsKey(path)) {
115+
node.nexts.put(path, new TrieNode());
116+
}
117+
node = node.nexts.get(path);
118+
node.pass++;
119+
}
120+
node.end++;
121+
}
122+
123+
public void erase(String word) {
124+
if (countWordsEqualTo(word) > 0) {
125+
TrieNode node = root;
126+
TrieNode next;
127+
node.pass--;
128+
for (int i = 0, path; i < word.length(); i++) {
129+
path = word.charAt(i);
130+
next = node.nexts.get(path);
131+
if (--next.pass == 0) {
132+
node.nexts.remove(path);
133+
return;
134+
}
135+
node = next;
136+
}
137+
node.end--;
138+
}
139+
}
140+
141+
public int countWordsEqualTo(String word) {
142+
TrieNode node = root;
143+
for (int i = 0, path; i < word.length(); i++) {
144+
path = word.charAt(i);
145+
if (!node.nexts.containsKey(path)) {
146+
return 0;
147+
}
148+
node = node.nexts.get(path);
149+
}
150+
return node.end;
151+
}
152+
153+
public int countWordsStartingWith(String pre) {
154+
TrieNode node = root;
155+
for (int i = 0, path; i < pre.length(); i++) {
156+
path = pre.charAt(i);
157+
if (!node.nexts.containsKey(path)) {
158+
return 0;
159+
}
160+
node = node.nexts.get(path);
161+
}
162+
return node.pass;
163+
}
164+
165+
}
82166

83167
}

src/class044/Code02_TrieTree.java

Lines changed: 97 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,124 @@
11
package class044;
22

3-
import java.util.HashMap;
3+
// 用固定数组实现前缀树,空间使用是静态的,路径是数组结构
4+
// 测试链接 : https://www.nowcoder.com/practice/7f8a8553ddbf4eaab749ec988726702b
5+
// 请同学们务必参考如下代码中关于输入、输出的处理
6+
// 这是输入输出处理效率很高的写法
7+
// 提交以下的code,提交时请把类名改成"Main",可以直接通过
8+
9+
import java.io.BufferedReader;
10+
import java.io.IOException;
11+
import java.io.InputStreamReader;
12+
import java.io.OutputStreamWriter;
13+
import java.io.PrintWriter;
14+
import java.util.Arrays;
415

5-
// 用类描述实现前缀树,路径是哈希表结构
6-
// 测试链接 : https://leetcode.cn/problems/implement-trie-ii-prefix-tree/
716
public class Code02_TrieTree {
817

9-
class Trie {
18+
public static int MAXN = 150001;
1019

11-
class TrieNode {
12-
public int pass;
13-
public int end;
14-
HashMap<Integer, TrieNode> nexts;
20+
public static int[][] tree = new int[MAXN][26];
1521

16-
public TrieNode() {
17-
pass = 0;
18-
end = 0;
19-
nexts = new HashMap<>();
20-
}
21-
}
22+
public static int[] end = new int[MAXN];
2223

23-
private TrieNode root;
24+
public static int[] pass = new int[MAXN];
25+
26+
public static int cnt;
27+
28+
public static void build() {
29+
cnt = 1;
30+
}
2431

25-
public Trie() {
26-
root = new TrieNode();
32+
public static void insert(String word) {
33+
int cur = 1;
34+
pass[cur]++;
35+
for (int i = 0, path; i < word.length(); i++) {
36+
path = word.charAt(i) - 'a';
37+
if (tree[cur][path] == 0) {
38+
tree[cur][path] = ++cnt;
39+
}
40+
cur = tree[cur][path];
41+
pass[cur]++;
2742
}
43+
end[cur]++;
44+
}
2845

29-
public void insert(String word) {
30-
TrieNode node = root;
31-
node.pass++;
32-
for (int i = 0, path; i < word.length(); i++) { // 从左往右遍历字符
33-
path = word.charAt(i);
34-
if (!node.nexts.containsKey(path)) {
35-
node.nexts.put(path, new TrieNode());
46+
public static void delete(String word) {
47+
if (search(word)) {
48+
int cur = 1;
49+
for (int i = 0, path; i < word.length(); i++) {
50+
path = word.charAt(i) - 'a';
51+
if (--pass[tree[cur][path]] == 0) {
52+
tree[cur][path] = 0;
53+
return;
3654
}
37-
node = node.nexts.get(path);
38-
node.pass++;
55+
cur = tree[cur][path];
3956
}
40-
node.end++;
57+
end[cur]--;
4158
}
59+
}
4260

43-
public void erase(String word) {
44-
if (countWordsEqualTo(word) > 0) {
45-
TrieNode node = root;
46-
TrieNode next;
47-
node.pass--;
48-
for (int i = 0, path; i < word.length(); i++) {
49-
path = word.charAt(i);
50-
next = node.nexts.get(path);
51-
if (--next.pass == 0) {
52-
node.nexts.remove(path);
53-
return;
54-
}
55-
node = next;
56-
}
57-
node.end--;
61+
public static boolean search(String word) {
62+
int cur = 1;
63+
for (int i = 0, path; i < word.length(); i++) {
64+
path = word.charAt(i) - 'a';
65+
if (tree[cur][path] == 0) {
66+
return false;
5867
}
68+
cur = tree[cur][path];
5969
}
70+
return end[cur] > 0;
71+
}
6072

61-
public int countWordsEqualTo(String word) {
62-
TrieNode node = root;
63-
for (int i = 0, path; i < word.length(); i++) {
64-
path = word.charAt(i);
65-
if (!node.nexts.containsKey(path)) {
66-
return 0;
67-
}
68-
node = node.nexts.get(path);
73+
public static int prefixNumber(String pre) {
74+
int cur = 1;
75+
for (int i = 0, path; i < pre.length(); i++) {
76+
path = pre.charAt(i) - 'a';
77+
if (tree[cur][path] == 0) {
78+
return 0;
6979
}
70-
return node.end;
80+
cur = tree[cur][path];
81+
}
82+
return pass[cur];
83+
}
84+
85+
public static void clear() {
86+
for (int i = 1; i <= cnt; i++) {
87+
Arrays.fill(tree[i], 0);
88+
end[i] = 0;
89+
pass[i] = 0;
7190
}
91+
}
92+
93+
public static int m, op;
7294

73-
public int countWordsStartingWith(String pre) {
74-
TrieNode node = root;
75-
for (int i = 0, path; i < pre.length(); i++) {
76-
path = pre.charAt(i);
77-
if (!node.nexts.containsKey(path)) {
78-
return 0;
95+
public static String[] splits;
96+
97+
public static void main(String[] args) throws IOException {
98+
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
99+
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
100+
String line = null;
101+
while ((line = in.readLine()) != null) {
102+
build();
103+
m = Integer.valueOf(line);
104+
for (int i = 1; i <= m; i++) {
105+
splits = in.readLine().split(" ");
106+
op = Integer.valueOf(splits[0]);
107+
if (op == 1) {
108+
insert(splits[1]);
109+
} else if (op == 2) {
110+
delete(splits[1]);
111+
} else if (op == 3) {
112+
out.println(search(splits[1]) ? "YES" : "NO");
113+
} else if (op == 4) {
114+
out.println(prefixNumber(splits[1]));
79115
}
80-
node = node.nexts.get(path);
81116
}
82-
return node.pass;
117+
clear();
83118
}
84-
119+
out.flush();
120+
in.close();
121+
out.close();
85122
}
86123

87124
}

0 commit comments

Comments
 (0)