问题:
In English, we have a concept called root
, which can be followed by some other words to form another longer word - let's call this word successor
. For example, the root an
, followed by other
, which can form another word another
.
Now, given a dictionary consisting of many roots and a sentence. You need to replace all the successor
in the sentence with the root
forming it. If a successor
has many roots
can form it, replace it with the root with the shortest length.
You need to output the sentence after the replacement.
Example 1:
Input: dict = ["cat", "bat", "rat"] sentence = "the cattle was rattled by the battery" Output: "the cat was rat by the bat"
Note:
- The input will only have lower-case letters.
- 1 <= dict words number <= 1000
- 1 <= sentence words number <= 1000
- 1 <= root length <= 100
- 1 <= sentence words length <= 1000
解决:
① 对dict排序之后查找即可。
class Solution {//58ms
public String replaceWords(List<String> dict, String sentence) {//58ms
//dict.sort((a, b) -> a.length() - b.length());
//Collections.sort(dict, Comparator.comparingInt(String::length));
Collections.sort(dict, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.length() - o2.length();
}
});
String[] str = sentence.split(" ");
for (int i = 0;i < str.length;i ++){
String word = str[i];
for (String d : dict){
if (word.startsWith(d)){
str[i] = d;
break;
}
}
}
return String.join(" ",str);
}
}
② 使用前缀树。
public class Solution { //34ms
TrieNode root = new TrieNode();
public String replaceWords(List<String> dict, String sentence) {
StringBuilder sb = new StringBuilder();
String[] words = sentence.split(" ");
for (String word : dict) {
build(word);
}
for (String word : words) {
if (sb.length() > 0) {
sb.append(" ");
}
sb.append(next(word));
}
return sb.toString();
}
public void build(String word) {
TrieNode curRoot = root;
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (curRoot.children[c - 'a'] == null) {
curRoot.children[c - 'a'] = new TrieNode();
}
curRoot = curRoot.children[c - 'a'];
}
curRoot.isTail = true;
}
public String next(String word) {
TrieNode curRoot = root;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (curRoot.children[c - 'a'] == null) {
break;
}
sb.append(c);
curRoot = curRoot.children[c - 'a'];
if (curRoot.isTail) return sb.toString();
}
return word;
}
}
class TrieNode {
TrieNode[] children;
boolean isTail = false;
public TrieNode() {
children = new TrieNode[26];
}
}
③
class Solution { //28ms
public String replaceWords(List<String> dict, String sentence) {
String[] words = sentence.split(" ");
Trie trie = new Trie();
for(String w : dict) {
trie.add(w, 0);
}
StringBuilder sb = new StringBuilder();
for(String w : words) {
if(sb.length() != 0) {
sb.append(' ');
}
sb.append(trie.replace(w, 0));
}
return sb.toString();
}
private static class Trie {
public Trie[] next = new Trie[26];
public String value = null;
public Trie() {}
public void add(String word, int index) {
if(index == word.length()) {
value = word;
}else {
int nextIndex = word.charAt(index) - 'a';
if(next[nextIndex] == null) {
next[nextIndex] = new Trie();
}
next[nextIndex].add(word, index+1);
}
}
public String replace(String word, int index) {
if(value != null) {
return value;
}
if(index == word.length()) {
return word;
} else {
int nextIndex = word.charAt(index) - 'a';
if(next[nextIndex] == null) {
return word;
}
return next[nextIndex].replace(word, index+1);
}
}
}
}