833. 字符串中的查找与替换

41 阅读1分钟

题目

你会得到一个字符串 s (索引从 0 开始),你必须对它执行 k 个替换操作。替换操作以三个长度均为 k 的并行数组给出:indicessources,  targets

要完成第 i 个替换操作:

  1. 检查 子字符串  sources[i] 是否出现在 原字符串 s 的索引 indices[i] 处。
  2. 如果没有出现, 什么也不做 。
  3. 如果出现,则用 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", indices = [0,2], sources = ["a","cd"], targets = ["eee","ffff"]
输出: "eeebffff"
解释: "a" 从 s 中的索引 0 开始,所以它被替换为 "eee""cd" 从 s 中的索引 2 开始,所以它被替换为 "ffff"

示例 2:

输入: s = "abcd", indices = [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 <= indices[i] < s.length
  • 1 <= sources[i].length, targets[i].length <= 50
  • s 仅由小写英文字母组成
  • sources[i] 和 targets[i] 仅由小写英文字母组成

题解

  1. s长度为 n, 创建一个长度 为 nreplace列表
  2. 遍历indices数组,如果字符串sindices[i]位置开始的sources[i]子串相同,则记录下s中替换的位置和对应替换数组中的位置replace[indices[i]] = i;
  3. 声明res = [] 遍历字符串s, 初始化 i = 0, 如果 replace[i]不存在,那么表示无需替换,把s[i]添加到res, 然后移动到下一个字符i++, 如果replace[i]不为空,那么把targets[replace[i]]加入到答案,然后跳过当前对应的source[i]的字符串即i += sources[replace[i]].length

复杂度分析

时间复杂度: O(n + ml), 其中 n是字符串 s 的长度, m是数组的indices的长度, l是数组 sourcestargets的平均长度

空间复杂度:O(n + ml), 哈希表需要的空间为O(m), 在替换操作中进行比较时,如果使用的语言支持无拷贝的切片操作,那么需要空间为O(1), 否则需要O(n + ml)的辅助空间

代码

const n = s.length;
    const replaces = new Array(n).fill(-1);
    for (let k = 0; k < indices.length; k++) {
        const [i, src] = [indices[k], sources[k]];
        if (s.startsWith(src, i)) {
            replaces[i] = k;
        }
    }
    const ans = [];
    for (let i = 0; i < n; ) {
        if (replaces[i] >= 0) {
            ans.push(targets[replaces[i]]);
            i += sources[replaces[i]].length;
        } else {
            ans.push(s[i]);
            i++;
        }
    }
    return ans.join('');