1. 程式人生 > >648. Replace Words

648. Replace Words

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: Solution 1 : hash map We can check the prefixes directly. For each word in the sentence, we'll look at successive prefixes and see if we saw them before. def replaceWords(self, roots, sentence): rootset
= set(roots) def replace(word): for i in xrange(1, len(word)): if word[:i] in rootset: return word[:i] return word return " ".join(map(replace, sentence.split())) class Solution { public String replaceWords(List<String> dict, String sentence) {
// convert the list of words to set of words // traversing the string sentence, check every possible prefix of each word, // see if exists in the dictionary, if it is , replace ith // if not exists, keep the original word if(dict == null || dict.size() == 0) return sentence; Set<String> set = new HashSet<>(dict); StringBuilder sb = new StringBuilder(); for(String word : sentence.split(" ")){ String prefix = ""; for(int i = 1; i <= word.length(); i++){ // i = 1, i <= word.length() prefix = word.substring(0, i); if(set.contains(prefix)) break; } // if found a root, or prefix, append, if not, we will have prefix has all the chars at the end sb.append(prefix).append(" "); } sb.setLength(sb.length() - 1); // have to setLength first before convert it to string return sb.toString(); } } Solution 2 : trie build trie with words from the dictionary Traverse the sentence word by word, check If each word has a prefix in the dictionary, if so, replace the word in the sentence with the prefix // not tested , others code public String replaceWords(List<String> dict, String sentence){ String[] tokens = sentence.split(" "); TrieNode trie = buildTrie(dict); return replaceWords(tokens, trie); } private String replaceWords(String[] tokens, TrieNode root){ StringBuilder sb = new StringBuilder(); for(String token : tokens){ sb.append(getShortestReplacement(token, root)).append(" "); } return sb.substring(0, sb.length() - 1); // sb.susbtirng() returns a string ??? // String substring() : This method has two variants and returns a new string that is a substring of this string. } private String getShortestReplacement(String token, TrieNode root){ TrieNode cur = root; StringBuilder sb = new StringBuilder(); for(char c : token.toCharArray()){ sb.append(c); if(cur.children[c - 'a'] != null){ if(cur.children[c - 'a'].isWord){ return sb.toString(); } cur = cur.children[c - 'a']; }else{ return token; // ? } } return token; // ? } private TrieNode buildTrie(List<String> dict){ TrieNode root = new TrieNode(' '); // not the normal way of building trie for(String word : dict){ TrieNode cur = root; for(char c : word.toCharArray()){ if(cur.children[c - 'a'] == null){ cur.children[c - 'a'] = new TrieNode(c); } cur = cur.children[c - 'a']; } cur.isWord = true; } return root; } public class TrieNode{ char val; TrieNode[] children; boolean isWord; public TrieNode(char val){ this.val = val; this.children = new TrieNode[26]; this.isWord = false; } } }