Given a list of strings words
representing an English Dictionary, find the longest word in words
that can be built one character at a time by other words in words
. If there is more than one possible answer, return the longest word with the smallest lexicographical order.
If there is no answer, return the empty string.
Example 1:
Input:
words = ["w","wo","wor","worl", "world"]
Output: "world"
Explanation:
The word "world" can be built one character at a time by "w", "wo", "wor", and "worl".
思路1: 用trie存word,然后扫描两遍;扫描第二次的时候,看每一步是否是isword,如果是,更新最长的word,如果跟最长的wordlength 相等,compareword,取lexicographical order最小的;
class Solution {
class TrieNode {
public TrieNode[] children;
public boolean isword;
public String word;
public TrieNode() {
this.children = new TrieNode[26];
this.isword = false;
this.word = null;
}
}
class Trie {
public TrieNode root;
public Trie() {
this.root = new TrieNode();
}
public void insertWord(String word) {
TrieNode cur = root;
for(int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if(cur.children[c - 'a'] == null) {
cur.children[c - 'a'] = new TrieNode();
}
cur = cur.children[c - 'a'];
}
cur.isword = true;
cur.word = word;
}
public boolean searchWord(String word) {
TrieNode cur = root;
for(int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if(cur.children[c - 'a'] == null || !cur.children[c - 'a'].isword) {
return false;
}
cur = cur.children[c - 'a'];
}
return cur.isword;
}
}
public String longestWord(String[] words) {
String longestWord = "";
Trie trie = new Trie();
for(String word: words) {
trie.insertWord(word);
}
for(String word: words) {
if(trie.searchWord(word)) {
if(word.length() > longestWord.length()
|| (word.length() == longestWord.length() && word.compareTo(longestWord) < 0)) {
longestWord = word;
}
}
}
return longestWord;
}
}
思路2:用trie做,可以做到O(n*L); 这题巧妙的是,build trie之后,可以bfs,层级的搜,要得到smallest lexicographical order.那么我最后搜集到的res,就是字典序最小的,因为是从后往前搜,然后最后一个答案就是最前面的;
class Solution {
public class TrieNode {
public TrieNode[] children;
public String word;
public boolean isword;
public TrieNode () {
this.children = new TrieNode[26];
this.word = null;
this.isword = false;
}
}
public class Trie {
public TrieNode root;
public Trie() {
this.root = new TrieNode();
}
public void insert(String word) {
TrieNode cur = root;
for(int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if(cur.children[c - 'a'] == null) {
cur.children[c - 'a'] = new TrieNode();
}
cur = cur.children[c - 'a'];
}
cur.isword = true;
cur.word = word;
}
}
public String longestWord(String[] words) {
Trie trie = new Trie();
for(String word: words) {
trie.insert(word);
}
String result = "";
Queue<TrieNode> queue = new LinkedList<>();
queue.offer(trie.root);
while(!queue.isEmpty()) {
int size = queue.size();
for(int i = 0; i < size; i++) {
TrieNode node = queue.poll();
for(int j = 25; j >= 0; j--) {
if(node.children[j] != null && node.children[j].isword) {
result = node.children[j].word;
queue.offer(node.children[j]);
}
}
}
}
return result;
}
}