1+
2+
3+ // LeetCode 104
4+
5+
6+ // [ 2. Trie树 ]
7+
8+ // 从最短的字符串开始建树,后面下一个,如果减1能找到,插入并记录为rst
9+ public String longestWord (String [] words ) {
10+ Set <Integer > set = new TreeSet <>();
11+ HashMap <Integer , List <String >> map = new HashMap <>();
12+ TrieNode p = root ;
13+
14+ for (int i = 0 ; i < words .length ; i ++) {
15+ int len = words [i ].length ();
16+ set .add (len );
17+ List <String > list = null ;
18+ if (map .containsKey (len )){
19+ list = map .get (len );
20+ }else {
21+ list = new ArrayList <>();
22+ }
23+ list .add (words [i ]);
24+ map .put (len , list );
25+ }
26+
27+ // 去重,排序
28+ int [] wordsLen = new int [set .size ()];
29+ int k = 0 ;
30+ for (Integer n : set ) {
31+ wordsLen [k ++] = n ;
32+ }
33+ Arrays .sort (wordsLen );
34+ String rst = "" ;
35+ // 按word长度递增顺序,开始建trie树
36+ // 先用word去掉尾字符在trie树中查询,找到rst记录,并插入树
37+ for (int i = 0 ; i < wordsLen .length ; i ++) {
38+ int len = wordsLen [i ];
39+ List <String > list = map .get (len );
40+ for (String word : list ){
41+ char [] text = word .toCharArray ();
42+ char [] txt = Arrays .copyOf (text , text .length -1 );
43+ if (text .length > 1 ){
44+ if (find (txt )){
45+ insert (text );
46+ if (rst .length () == word .length ()){
47+ if (rst .compareTo (word ) > 0 ){
48+ rst = word ;
49+ }
50+ }else {
51+ rst = word ;
52+ }
53+ }
54+ }else {
55+ if (rst .length () == 0 ){
56+ rst = word ;
57+ }else if (rst .compareTo (word ) > 0 ){
58+ rst = word ;
59+ }
60+ insert (text );
61+ }
62+ }
63+ }
64+
65+ return rst ;
66+ }
67+
68+ class TrieNode {
69+
70+ public char data ;
71+ public TrieNode [] children = new TrieNode [26 ];
72+ public boolean isEndingChar = false ;
73+ public TrieNode (char data ){
74+ this .data = data ;
75+ }
76+ }
77+
78+ // root
79+ TrieNode root = new TrieNode ('\\' );
80+
81+ // 插入一个字符
82+ public void insert (char [] text ){
83+ TrieNode p = root ;
84+
85+ int len = text .length ;
86+ for (int i = 0 ; i < len ; i ++) {
87+ // 字符插入位置索引
88+ int index = text [i ] - 'a' ;
89+ // 根据索引插入children中。如果已经存在则不处理
90+ if (p .children [index ] == null ){
91+ p .children [index ] = new TrieNode (text [i ]);
92+ }
93+ // 到下一层遍历
94+ p = p .children [index ];
95+ }
96+ p .isEndingChar = true ;
97+ }
98+
99+
100+ // 查找一个字符串
101+ public boolean find (char [] pattern ){
102+ TrieNode p = root ;
103+
104+ for (int i = 0 ; i < pattern .length ; i ++) {
105+ int index = pattern [i ] - 'a' ;
106+ if (p .children [index ] == null ){
107+ return false ;
108+ }
109+ // 继续向下一层查询
110+ p = p .children [index ];
111+ }
112+ if (p .isEndingChar == false ){
113+ return true ;
114+ }
115+
116+ return true ;
117+ }
118+
119+
120+
121+
122+
123+ // [ 1. 哈希表 ]
124+
125+
126+ // 通过单词长度递减,然后在words中查询,如果能找到,符合题目要求
127+ public String longestWord1 (String [] words ) {
128+ int [] wordsLen = new int [words .length ];
129+ HashMap <String , Integer > map = new HashMap <>();
130+ TrieNode p = root ;
131+
132+ for (int i = 0 ; i < words .length ; i ++) {
133+ int len = words [i ].length ();
134+ wordsLen [i ] = len ;
135+ if (!map .containsKey (words [i ])){
136+ map .put (words [i ], 1 );
137+ }
138+ }
139+
140+ String rst = "" ;
141+ for (int i = 0 ; i < words .length ; i ++) {
142+ String wd = words [i ];
143+ int len = wd .length ();
144+ int j = 0 ;
145+ for (j = 1 ; j < len ; j ++) {
146+ wd = wd .substring (0 , len - j );
147+ // 子串在words中没有
148+ if (!map .containsKey (wd )){
149+ break ;
150+ }
151+ }
152+ if (j == len ){
153+ if (rst .length () == 0 || rst .length () < len ){
154+ rst = words [i ];
155+ }else if (rst .length () == len && rst .compareTo (words [i ]) > 0 ){
156+ rst = words [i ];
157+ }
158+ }
159+ }
160+ return rst ;
161+ }
0 commit comments