Description
Given a list of words, write a program to find the longest word made of other words in the list. If there are more than one answer, return the one that has smallest lexicographic order. If no answer, return an empty string.
Example:
Input: ["cat","banana","dog","nana","walk","walker","dogwalker"]
Output: "dogwalker"
Explanation: "dogwalker" can be made of "dog" and "walker".
Note:
0 <= len(words) <= 100
1 <= len(words[i]) <= 100
Solutions
Solution 1
Python3 Java Go Swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 class Trie :
def __init__ ( self ):
self . children = [ None ] * 26
self . is_end = False
def insert ( self , word ):
node = self
for c in word :
idx = ord ( c ) - ord ( 'a' )
if node . children [ idx ] is None :
node . children [ idx ] = Trie ()
node = node . children [ idx ]
node . is_end = True
def search ( self , word ):
node = self
for c in word :
idx = ord ( c ) - ord ( 'a' )
if node . children [ idx ] is None :
return False
node = node . children [ idx ]
return node . is_end
class Solution :
def longestWord ( self , words : List [ str ]) -> str :
def cmp ( a , b ):
if len ( a ) != len ( b ):
return len ( a ) - len ( b )
return - 1 if a > b else 1
def dfs ( w ):
return not w or any (
trie . search ( w [: i ]) and dfs ( w [ i :]) for i in range ( 1 , len ( w ) + 1 )
)
words . sort ( key = cmp_to_key ( cmp ))
trie = Trie ()
ans = ""
for w in words :
if dfs ( w ):
ans = w
trie . insert ( w )
return ans
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 class Trie {
Trie [] children = new Trie [ 26 ] ;
boolean isEnd ;
void insert ( String word ) {
Trie node = this ;
for ( char c : word . toCharArray ()) {
c -= 'a' ;
if ( node . children [ c ] == null ) {
node . children [ c ] = new Trie ();
}
node = node . children [ c ] ;
}
node . isEnd = true ;
}
boolean search ( String word ) {
Trie node = this ;
for ( char c : word . toCharArray ()) {
c -= 'a' ;
if ( node . children [ c ] == null ) {
return false ;
}
node = node . children [ c ] ;
}
return node . isEnd ;
}
}
class Solution {
private Trie trie = new Trie ();
public String longestWord ( String [] words ) {
Arrays . sort ( words , ( a , b ) -> {
if ( a . length () != b . length ()) {
return a . length () - b . length ();
}
return b . compareTo ( a );
});
String ans = "" ;
for ( String w : words ) {
if ( dfs ( w )) {
ans = w ;
}
trie . insert ( w );
}
return ans ;
}
private boolean dfs ( String w ) {
if ( "" . equals ( w )) {
return true ;
}
for ( int i = 1 ; i <= w . length (); ++ i ) {
if ( trie . search ( w . substring ( 0 , i )) && dfs ( w . substring ( i ))) {
return true ;
}
}
return false ;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 type Trie struct {
children [ 26 ] * Trie
isEnd bool
}
func newTrie () * Trie {
return & Trie {}
}
func ( this * Trie ) insert ( word string ) {
node := this
for _ , c := range word {
c -= 'a'
if node . children [ c ] == nil {
node . children [ c ] = newTrie ()
}
node = node . children [ c ]
}
node . isEnd = true
}
func ( this * Trie ) search ( word string ) bool {
node := this
for _ , c := range word {
c -= 'a'
if node . children [ c ] == nil {
return false
}
node = node . children [ c ]
}
return node . isEnd
}
func longestWord ( words [] string ) string {
sort . Slice ( words , func ( i , j int ) bool {
a , b := words [ i ], words [ j ]
if len ( a ) != len ( b ) {
return len ( a ) < len ( b )
}
return a > b
})
trie := newTrie ()
var dfs func ( string ) bool
dfs = func ( w string ) bool {
if len ( w ) == 0 {
return true
}
for i := 1 ; i <= len ( w ); i ++ {
if trie . search ( w [: i ]) && dfs ( w [ i :]) {
return true
}
}
return false
}
ans := ""
for _ , w := range words {
if dfs ( w ) {
ans = w
}
trie . insert ( w )
}
return ans
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 class Trie {
var children = [ Trie ?]( repeating : nil , count : 26 )
var isEnd = false
func insert ( _ word : String ) {
var node = self
for ch in word {
let index = Int ( ch . asciiValue ! - Character ( "a" ). asciiValue !)
if node . children [ index ] == nil {
node . children [ index ] = Trie ()
}
node = node . children [ index ] !
}
node . isEnd = true
}
func search ( _ word : String ) -> Bool {
var node = self
for ch in word {
let index = Int ( ch . asciiValue ! - Character ( "a" ). asciiValue !)
if node . children [ index ] == nil {
return false
}
node = node . children [ index ] !
}
return node . isEnd
}
}
class Solution {
func longestWord ( _ words : [ String ]) -> String {
var words = words . sorted ( by : { $0 . count < $1 . count || ( $0 . count == $1 . count && $0 > $1 ) })
let trie = Trie ()
var dfs : (( String ) -> Bool ) !
dfs = { w in
if w . isEmpty {
return true
}
for i in 1. .. w . count {
if trie . search ( String ( w . prefix ( i ))) && dfs ( String ( w . suffix ( w . count - i ))) {
return true
}
}
return false
}
var ans = ""
for w in words {
if dfs ( w ) {
ans = w
}
trie . insert ( w )
}
return ans
}
}
GitHub