Trie of roots
Time O(total characters) Space O(root characters)Insert roots. For each word, walk the trie; if you reach a root node, use the prefix so far; if the path breaks, keep the word.
import java.util.*;
class Solution {
private static class Node {
Node[] next = new Node[26];
boolean isRoot;
}
public String replaceWords(List<String> dictionary, String sentence) {
Node root = new Node();
for (String w : dictionary) {
Node n = root;
for (char c : w.toCharArray()) {
if (n.next[c - 'a'] == null) n.next[c - 'a'] = new Node();
n = n.next[c - 'a'];
}
n.isRoot = true;
}
StringBuilder out = new StringBuilder();
for (String word : sentence.split(" ")) {
if (out.length() > 0) out.append(' ');
out.append(shortestRoot(root, word));
}
return out.toString();
}
private String shortestRoot(Node root, String word) {
Node n = root;
for (int i = 0; i < word.length(); i++) {
n = n.next[word.charAt(i) - 'a'];
if (n == null) return word;
if (n.isRoot) return word.substring(0, i + 1);
}
return word;
}
}Verdict: Linear in the input.