import java.util.*; //前缀树节点 class TrieNode { TrieNode[] chs ;//保存子节点 int count ;//以该节点结尾的前缀 的单词数量 boolean isEnd ;//该节点是否为一个单词的结尾 String word ;//该节点若为一个单词的结尾,保存这个单词 TrieNode() { this.chs = new TrieNode[26] ;//由于本题只涉及到26个小写字母,使用数组作为hash表(一般用Map) this.count = 0 ; this.isEnd = false ; this.word = null ; } } public class Solution { /** * * @param operators string字符串二维数组 the ops * @return string字符串一维数组 */ private TrieNode root = new TrieNode() ;//根节点不代表任何字母,根节点的儿子节点代表 单词首字母 public String[] trieU (String[][] operators) { List<String> list = new ArrayList<>() ; for(String[] arr : operators) { String opt = arr[0] ; String word = arr[1] ; switch(opt) { case "1": insert(word) ; break ; case "2": delete(word) ; break ; case "3": list.add(search(word) == true ? "YES" : "NO") ;break ; case "4": list.add(String.valueOf(prefixNumber(word))) ;break ; } } String res[] = new String[list.size()] ; return list.toArray(res) ; } public void insert(String word) { char[] arr = word.toCharArray() ; TrieNode cur = root ; TrieNode chs1[] = cur.chs ; for(int i = 0 ; i < arr.length ; i ++) { if(chs1[arr[i]-'a'] == null) { chs1[arr[i]-'a'] = new TrieNode() ; chs1[arr[i]-'a'].count = 1 ; } else { chs1[arr[i]-'a'].count ++ ; } if(i == arr.length - 1) { chs1[arr[i]-'a'].isEnd = true ; chs1[arr[i]-'a'].word = word ; } else { chs1 = chs1[arr[i]-'a'].chs ;//向下层迭代 } } } public void delete(String word) { if(!search(word)) return ; char[] arr = word.toCharArray() ; TrieNode cur = root ; TrieNode chs1[] = cur.chs ; for(int i = 0 ; i < arr.length ; i ++) { chs1[arr[i]-'a'].count -- ; if(chs1[arr[i]-'a'].count == 0) { chs1[arr[i]-'a'] = null ; return ; } if(i == arr.length - 1) { chs1[arr[i]-'a'].isEnd = false ; chs1[arr[i]-'a'].word = null ; } else { chs1 = chs1[arr[i]-'a'].chs ; } } } public boolean search(String word) { TrieNode cur = root ; char[] arr = word.toCharArray() ; TrieNode chs1[] = cur.chs ; for(int i = 0 ; i < arr.length ; i ++) { if(chs1[arr[i]-'a'] == null) return false ; if(i == arr.length-1 && chs1[arr[i]-'a'].isEnd == true) return true ; chs1 = chs1[arr[i]-'a'].chs ; } return false ; } public int prefixNumber(String pre) { TrieNode cur = root ; char[] arr = pre.toCharArray() ; TrieNode chs1[] = cur.chs ; for(int i = 0 ; i < arr.length ; i ++) { if(chs1[arr[i]-'a'] == null) return 0 ; if(i == arr.length - 1) return chs1[arr[i]-'a'].count ; chs1 = chs1[arr[i]-'a'].chs ; } return 0 ; } }