题目链接:
https://leetcode-cn.com/problems/re-space-lcci/
难度:中等
面试题 17.13. 恢复空格
哦,不!你不小心把一个长篇文章中的空格、标点都删
掉了,并且大写也弄成了小写。像句子"I reset the computer.
It still didn’t boot!"已经变成了"iresetthecomputeritstilldidntboot"。
在处理标点符号和大小写之前,你得先把它断成词语。当然
了,你有一本厚厚的词典dictionary,不过,有些词没在词
典里。假设文章用sentence表示,设计一个算法,把文章断
开,要求未识别的字符最少,返回未识别的字符数。
注意:本题相对原题稍作改动,只需返回未识别的字符数
示例:
输入:
dictionary = ["looked","just","like","her","brother"]
sentence = "jesslookedjustliketimherbrother"
输出: 7
解释: 断句后为"jess looked just like tim her
brother",共7个未识别字符。
提示:
0 <= len(sentence) <= 1000
dictionary中总字符数不超过 150000。
你可以认为dictionary和sentence中只包含小写字母。
我笑了 这算中等难度??? 好TM难 只能选择看解析。。。
思路一 Trie + 动态规划
今天 又接触到一个新的东西 字典树Trie 典型的空间换时间
动态规划dp[i] 表示前i个字符最少的未识别的字符数量,从前往后计算。动态转化方程
找到了:dp[i]=min(dp[i],dp[j-1])
解释: j->i 组成的字符串 即sentence[j-1... i-1]
未找到:dp[i]=dp[i-1]+1
tree 字典树 倒叙插入
// 字典树
class Trie {
public:
Trie* next[26] = {nullptr};
// 标识
bool isEnd;
Trie() {
isEnd = false;
}
void insert(string s) {
Trie* curPos = this;
// 下标共26 分别代表各个字母
for (int i = s.length() - 1; i >= 0; --i) {
int t = s[i] - 'a';
// 若为空 初始化
if (curPos->next[t] == nullptr) {
curPos->next[t] = new Trie();
}
// 非空 则表示所对应的字母存在
// 更新curPos 对字符串当前状态更新
curPos = curPos->next[t];
}
// 到此处是否为一个单词
curPos->isEnd = true;
}
};
class Solution {
public:
int respace(vector<string>& dictionary, string sentence) {
// inf为无穷大数 (可以认为)。。。
// 据说这样设置有好处
// 无穷大加一个有穷的数依然是无穷大
// 无穷大加无穷大还是无穷大
int n = sentence.length(), inf = 0x3f3f3f3f;
// 初始化字典树 trie
Trie* root = new Trie();
for (auto& word: dictionary) {
root->insert(word);
}
// 初始化dp
vector<int> dp(n + 1, inf);
dp[0] = 0;
for (int i = 1; i <= n; ++i) {
// 假设未找到
dp[i] = dp[i - 1] + 1;
Trie* curPos = root;
// 开始寻找
for (int j = i; j >= 1; --j) {
int t = sentence[j - 1] - 'a';
// 查找失败 推出
if (curPos->next[t] == nullptr) {
break;
} else if (curPos->next[t]->isEnd) {
// 查找成功 i到j为一个单词
dp[i] = min(dp[i], dp[j - 1]);
}
// dp[i]==0 那还查个毛线 推出呗
if (dp[i] == 0) {
break;
}
// 更新curPos继续查找
curPos = curPos->next[t];
}
}
return dp[n];
}
};
官方题解还有一种方法 个人感觉还是动态规划的思路 只不过查找方式变了 将字符串转换为整数类型进行查找 不过没研究透彻 过几天再说。。。。