题目描述
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
思路分析
这题的思路最简单的就是暴力遍历。首先要解决的问题就是将输入的sentence按照空格进行split。如果是其他语言很自然的就会想到split方法,但是可惜C++的STL并没有这个API。于是这里很巧妙的用了stringstream。可以模拟读入,按照空格分隔开每个单词。
然后就是对比,如果遍历的暴力对比的话,那么每次就是O(N),这个复杂度太高了。但是如果使用hash based的数据结构,比如unordered set或者unordered map。
那么具体实现起来,就是将所有的prefix存在unordered set,然后对于每个单词的每个substr来确定是否包含这个prefix。
复杂度
时间复杂度为O(m) m是sentence中字母的个数。
代码
#include <iostream>
#include <algorithm>
#include <string>
#include <set>
#include <sstream>
class Solution {
public:
string replaceWords(vector<string>& dict, string sentence) {
std::unordered_set<std::string> set(dict.begin(), dict.end());
istringstream ss(sentence);
string word;
string result = "";
while (ss >> word) {
for (int i = 0; i < word.size(); i++) {
if (set.count(word.substr(0, i))) {
word = word.substr(0, i);
break;
}
}
result += " " + word;
}
return result.substr(1);
}
};