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 theroot
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"
題意:用字典中存在的前綴代替句子中的單詞,若有多個前綴可以表示單詞,則選擇最短的一個
用基礎字典樹即可解決,將字典中的前綴字符串存入字典樹中,遍歷每個句子的單詞,找到最短的前綴返回即可
字典樹結構:
struct Trie{
int val; //表示此位置是否有前綴結束
vector<Trie*> child;
Trie():child(vector<Trie*>(26,NULL)),val(-1){}
};
首先是字典樹的創建(插入)過程,題目只要返回最短的前綴字符串,在插入時對於每一個字符串的最後一個字符節點的val設置爲0表示此位置爲結束位置。
void insert(string s,Trie* root){
for(int i=0;i<s.size();i++){
int num = s[i]-'a';
if(root->child[num] == NULL)
{
root->child[num] = new Trie();
}
root = root->child[num];
if(i!=s.size()-1&&root->val!=0)
root->val = 1;
else root->val = 0; //若此位置爲結束位置,將val設置爲0
}
}
查找時,遇到val爲0的字符節點就可以返回,這樣就能保證返回的前綴爲最短的,若字典樹中不存在此單詞的前綴,那麼查找停止位置的val不等於0;
string search(string s,Trie* root){
string res = "";
for(int i=0;i<s.size();i++){
int num = s[i] -'a';
if(root->child[num] == NULL)
break;
root = root->child[num];
res += s[i];
if(root->val == 0)
return res;
}
if(root->val == 0)
return res;
else return s;
}
string replaceWords(vector<string>& dict, string sentence) {
Trie *root = new Trie();
string res = "";
for(string s:dict)
insert(s,root);
stringstream ss(sentence);
string s;
int sign = 1;
while(ss>>s){
string temp = search(s,root);
if(sign!=1)
res += " ";
if(temp.empty())
res +=s;
else res +=temp;
sign++;
}
return res;
}