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
| class Solution { private String res;
private static class Node { Map<Character, Node> children; boolean isWord;
Node(Map<Character, Node> _children) { this.children = _children; isWord = false; } }
private void addWord(Node root, String word) { Node ptr = root; for (char letter : word.toCharArray()) { ptr.children.putIfAbsent(letter, new Node(new HashMap<>())); ptr = ptr.children.get(letter); } ptr.isWord = true; }
private void dfs(Node node, StringBuilder curr) { boolean hasLongerWord = false; for (Map.Entry<Character, Node> entry : node.children.entrySet()) { if (entry.getValue().isWord) { curr.append(entry.getKey()); dfs(entry.getValue(), curr); hasLongerWord = true; curr.setLength(curr.length() - 1); } } if (!hasLongerWord) { if (curr.length() > res.length() || (curr.length() == res.length() && curr.toString().compareTo(res) < 0)) { res = curr.toString(); } } }
public String longestWord(String[] words) { Node root = new Node(new HashMap<>()); for (String word : words) { addWord(root, word); } res = ""; dfs(root, new StringBuilder()); return res; } }
|
使用Trie把每个word存起来. 然后backtrack, 只走node被标记为word的地方. 直到走不动. 如何知道走不动? 我使用了一个flag, 如果往下走了, 这个flag是true, 否则就是false. 于是这样能cover到两种走不动的情况: 一种是没有child了, 一种是下面的child都不是word. 遇到flag是false时, 我们就要看当前的word是否比res长或者如果和res一样长是否比它更靠前.