11package class044 ;
22
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 ;
15-
3+ // 用类描述实现前缀树,路径是数组结构
4+ // 测试链接 : https://leetcode.cn/problems/implement-trie-ii-prefix-tree/
165public class Code01_TrieTree {
176
18- public static int MAXN = 150001 ;
19-
20- public static int [][] tree = new int [MAXN ][26 ];
7+ class Trie {
218
22- public static int [] end = new int [MAXN ];
9+ class TrieNode {
10+ public int pass ;
11+ public int end ;
12+ public TrieNode [] nexts ;
2313
24- public static int [] pass = new int [MAXN ];
14+ public TrieNode () {
15+ pass = 0 ;
16+ end = 0 ;
17+ nexts = new TrieNode [26 ];
18+ }
19+ }
2520
26- public static int cnt ;
21+ private TrieNode root ;
2722
28- public static void insert (String word ) {
29- int cur = 1 ;
30- pass [cur ]++;
31- for (int i = 0 , path ; i < word .length (); i ++) {
32- path = word .charAt (i ) - 'a' ;
33- if (tree [cur ][path ] == 0 ) {
34- tree [cur ][path ] = ++cnt ;
35- }
36- cur = tree [cur ][path ];
37- pass [cur ]++;
23+ public Trie () {
24+ root = new TrieNode ();
3825 }
39- end [cur ]++;
40- }
4126
42- public static void delete (String word ) {
43- if (search (word )) {
44- int cur = 1 ;
45- for (int i = 0 , path ; i < word .length (); i ++) {
46- path = word .charAt (i ) - 'a' ;
47- if (--pass [tree [cur ][path ]] == 0 ) {
48- tree [cur ][path ] = 0 ;
49- return ;
27+ public void insert (String word ) {
28+ TrieNode node = root ;
29+ node .pass ++;
30+ for (int i = 0 , path ; i < word .length (); i ++) { // 从左往右遍历字符
31+ path = word .charAt (i ) - 'a' ; // 由字符,对应成走向哪条路
32+ if (node .nexts [path ] == null ) {
33+ node .nexts [path ] = new TrieNode ();
5034 }
51- cur = tree [cur ][path ];
35+ node = node .nexts [path ];
36+ node .pass ++;
5237 }
53- end [ cur ]-- ;
38+ node . end ++ ;
5439 }
55- }
5640
57- public static boolean search (String word ) {
58- int cur = 1 ;
59- for (int i = 0 , path ; i < word .length (); i ++) {
60- path = word .charAt (i ) - 'a' ;
61- if (tree [cur ][path ] == 0 ) {
62- return false ;
41+ public void erase (String word ) {
42+ if (countWordsEqualTo (word ) > 0 ) {
43+ TrieNode node = root ;
44+ node .pass --;
45+ for (int i = 0 , path ; i < word .length (); i ++) {
46+ path = word .charAt (i ) - 'a' ;
47+ if (--node .nexts [path ].pass == 0 ) {
48+ node .nexts [path ] = null ;
49+ return ;
50+ }
51+ node = node .nexts [path ];
52+ }
53+ node .end --;
6354 }
64- cur = tree [cur ][path ];
6555 }
66- return end [cur ] > 0 ;
67- }
6856
69- public static int prefixNumber (String pre ) {
70- int cur = 1 ;
71- for (int i = 0 , path ; i < pre .length (); i ++) {
72- path = pre .charAt (i ) - 'a' ;
73- if (tree [cur ][path ] == 0 ) {
74- return 0 ;
57+ public int countWordsEqualTo (String word ) {
58+ TrieNode node = root ;
59+ for (int i = 0 , path ; i < word .length (); i ++) {
60+ path = word .charAt (i ) - 'a' ;
61+ if (node .nexts [path ] == null ) {
62+ return 0 ;
63+ }
64+ node = node .nexts [path ];
7565 }
76- cur = tree [ cur ][ path ] ;
66+ return node . end ;
7767 }
78- return pass [cur ];
79- }
80-
81- public static int m , op ;
82-
83- public static String [] splits ;
8468
85- public static void main (String [] args ) throws IOException {
86- BufferedReader in = new BufferedReader (new InputStreamReader (System .in ));
87- PrintWriter out = new PrintWriter (new OutputStreamWriter (System .out ));
88- String line = null ;
89- while ((line = in .readLine ()) != null ) {
90- cnt = 1 ;
91- m = Integer .valueOf (line );
92- for (int i = 1 ; i <= m ; i ++) {
93- splits = in .readLine ().split (" " );
94- op = Integer .valueOf (splits [0 ]);
95- if (op == 1 ) {
96- insert (splits [1 ]);
97- } else if (op == 2 ) {
98- delete (splits [1 ]);
99- } else if (op == 3 ) {
100- out .println (search (splits [1 ]) ? "YES" : "NO" );
101- } else if (op == 4 ) {
102- out .println (prefixNumber (splits [1 ]));
69+ public int countWordsStartingWith (String pre ) {
70+ TrieNode node = root ;
71+ for (int i = 0 , path ; i < pre .length (); i ++) {
72+ path = pre .charAt (i ) - 'a' ;
73+ if (node .nexts [path ] == null ) {
74+ return 0 ;
10375 }
76+ node = node .nexts [path ];
10477 }
105- for (int i = 1 ; i <= cnt ; i ++) {
106- Arrays .fill (tree [i ], 0 );
107- end [i ] = 0 ;
108- pass [i ] = 0 ;
109- }
78+ return node .pass ;
11079 }
111- out .flush ();
112- in .close ();
113- out .close ();
80+
11481 }
11582
11683}
0 commit comments