您的位置:首页 > 其它

HashTable-720-Longest Word in Dictionary

2018-01-19 21:31 459 查看
Description:

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".


Example 2:

Input:
words = ["a", "banana", "app", "appl", "ap", "apply", "apple"]
Output: "apple"
Explanation:
Both "apply" and "apple" can be built from other words in the dictionary. However, "apple" is lexicographically smaller than "apply".


Note:
All the strings in the input will only contain lowercase letters.
The length of words will be in the range [1, 1000].
The length of words[i] will be in the range [1, 30].


Solution:

//构造前缀树。前缀树中每个Node都包含一个字符c(root为0),以及end(用来存储字符串在words中的下标,在之后的DFS中方便取出字符串进行比较),以及一个Map(键为子节点对应的字符,值为子节点)。需要特别注意的是前缀树的构造方式,如果节点没有对应的子节点,则会新建节点,然后沿着该新建的节点继续向下构建(这就形成了一条路径,即为前缀)。
class Solution {
public String longestWord(String[] words) {
Trie trie = new Trie();
int index = 0;
for (String word: words) {
trie.insert(word, ++index); //indexed by 1
}
trie.words = words;
return trie.dfs();
}
}
class Node {
char c;
HashMap<Character, Node> children = new HashMap();
int end;
public Node(char c){
this.c = c;
}
}

class Trie {
Node root;
String[] words;
public Trie() {
root = new Node('0');
}

public void insert(String word, int index) {
Node cur = root;
for (char c: word.toCharArray()) {
cur.children.putIfAbsent(c, new Node(c));
cur = cur.children.get(c);
}
cur.end = index;
}

public String dfs() {
String ans = "";
Stack<Node> stack = new Stack();
stack.push(root);
while (!stack.empty()) {
Node node = stack.pop();
if (node.end > 0 || node == root) {
if (node != root) {
String word = words[node.end - 1];
if (word.length() > ans.length() ||
word.length() == ans.length() && word.compareTo(ans) < 0) {
ans = word;
}
}
for (Node nei: node.children.values()) {
stack.push(nei);
}
}
}
return ans;
}
}


Better Solution:

//注意,这里之所以没有像上一个解法用String.compareTo()是因为使用了数组,而数组的顺序就代表了字母的大小,所以同等大小,选在排在前面的。
class Solution {

private final int NUM_LETTERS = 26;

class Trie {
Trie[] next = new Trie[NUM_LETTERS];
String word = null;
}

Trie root = new Trie();

private void addWord(String s) {
Trie curr = root;
for(char c: s.toCharArray()) {
int index = c - 'a';
if(curr.next[index] == null) {
curr.next[index] = new Trie();
}
curr = curr.next[index];
}
curr.word = s;
}

public String longestWord(String[] words) {
root.word = "";
for(String word: words) {
addWord(word);
}
Trie curr = root;
return DFS(curr);
}

private String DFS(Trie curr) {
String result = curr.word;
for(int i = 0; i < NUM_LETTERS; i++) {
if(curr.next[i] != null && curr.next[i].word != null) {
String subResult = DFS(curr.next[i]);
if(subResult.length() > result.length()) {
result = subResult;
}
}
}
return result;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: