开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第29天,点击查看活动详情
一 描述
833. 字符串中的查找与替换 - 力扣(LeetCode)
你会得到一个字符串 s
(索引从 0
开始),你必须对它执行 k
个替换操作。替换操作以三个长度均为 k
的并行数组给出:indices
, sources
, targets
。
要完成第 i
个替换操作:
- 检查 子字符串
sources[i]
是否出现在 原字符串s
的索引indices[i]
处。 - 如果没有出现, 什么也不做 。
- 如果出现,则用
targets[i]
替换 该子字符串。 例如,如果s = "abcd"
,indices[i] = 0
,sources[i] = "ab"
,targets[i] = "eee"
,那么替换的结果将是"eeecd"
。
所有替换操作必须 同时 发生,这意味着替换操作不应该影响彼此的索引。测试用例保证元素间不会重叠 。
- 例如,一个 s = "abc" , indices = [0,1] , sources = ["ab","bc"] 的测试用例将不会生成,因为 "ab" 和 "bc" 替换重叠。
在对
s
执行所有替换操作后返回 结果字符串 。
子字符串 是字符串中连续的字符序列。
示例 1:
输入:s = "abcd", indexes = [0,2], sources = ["a","cd"], targets = ["eee","ffff"]
输出:"eeebffff"
解释:
"a" 从 s 中的索引 0 开始,所以它被替换为 "eee"。
"cd" 从 s 中的索引 2 开始,所以它被替换为 "ffff"。
示例 2:
输入:s = "abcd", indexes = [0,2], sources = ["ab","ec"], targets = ["eee","ffff"]
输出:"eeecd"
解释:
"ab" 从 s 中的索引 0 开始,所以它被替换为 "eee"。
"ec" 没有从原始的 S 中的索引 2 开始,所以它没有被替换。
提示:
- 1 <= s.length <= 1000
- k == indices.length == sources.length == targets.length
- 1 <= k <= 100
- 0 <= indexes[i] < s.length
- 1 <= sources[i].length, targets[i].length <= 50
- s 仅由小写英文字母组成
- sources[i] 和 targets[i] 仅由小写英文字母组成
二 分析
刚开始看这道题的时候,我没怎么审题,就直接用前缀树怼起来了,后面写好了才发现其实别人已经给出了匹配的起始点,只好重写。
大概思路就是,从左到右遍历字符串S,遇到匹配点的时候,检查从匹配点开始的子字符串与source数组中对应位置的字符串是否相等,如果相等则使用target对应位置处的字符串进行替换。
三 答案
class Solution {
public:
string findReplaceString(string S, vector<int>& indexes, vector<string>& sources, vector<string>& targets) {
string ans;
map<int, vector<string>> tree;
for (int i = 0; i < indexes.size(); i++) {
tree[indexes[i]] = {sources[i], targets[i]};
}
for (int i = 0; i < S.size(); i++) {
if (tree.count(i)) {
int j = i;
bool flag = true;
for (int j1 = 0; j1 < tree[i][0].size(); j1++) {
if (j >= S.size() || S[j] != tree[i][0][j1]) {
flag = false;
break;
}
j++;
}
if (flag) {
ans += tree[i][1];
i += tree[i][0].size() - 1;
continue;
}
}
ans += S[i];
}
return ans;
}
};