LeetCode 833. Find And Replace in String【字符串,哈希表,模拟】1460

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章中,我不仅会讲解多种解题思路及其优化,还会用多种编程语言实现题解,涉及到通用解法时更将归纳总结出相应的算法模板。

为了方便在PC上运行调试、分享代码文件,我还建立了相关的仓库:https://github.com/memcpy0/LeetCode-Conquest。在这一仓库中,你不仅可以看到LeetCode原题链接、题解代码、题解文章链接、同类题目归纳、通用解法总结等,还可以看到原题出现频率和相关企业等重要信息。如果有其他优选题解,还可以一同分享给他人。

由于本系列文章的内容随时可能发生更新变动,欢迎关注和收藏征服LeetCode系列文章目录一文以作备忘。

你会得到一个字符串 s (索引从 0 开始),你必须对它执行 k 个替换操作。替换操作以三个长度均为 k 的并行数组给出:indices, sources, 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:

cpp 复制代码
输入:s = "abcd", indices = [0,2], sources = ["a","cd"], targets = ["eee","ffff"]
输出:"eeebffff"
解释:
"a" 从 s 中的索引 0 开始,所以它被替换为 "eee"。
"cd" 从 s 中的索引 2 开始,所以它被替换为 "ffff"。

示例 2:

java 复制代码
输入: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] 仅由小写英文字母组成

解法 字符串+哈希表+模拟

设 s s s 长度为 n n n ,创建一个长为 n n n 的 m a t c h I n d e x matchIndex matchIndex 列表,初始化每个元素为 − 1 -1 −1 。

遍历每个替换操作。对于第 i i i 个替换操作,如果从 indices i \textit{indices}i indicesi 开始的字符串有前缀 sources i \textit{sources}i sourcesi ,则可以替换成 target i \textit{target}i targeti 。例如 s="abcd" ,s[1:]="bcd" 有前缀 "bc" 。此时记录 m a t c h I n d e x i n d i c e s \[ i ] = i matchIndexindices\[i]=i matchIndexindices\[i]=i ,后面的 i i i 指的是 t a r g e t i targeti targeti ,表示「从原串的 i n d i c e s i indicesi indicesi 位置开始要进行替换,替换后从 s o u r c e s i sourcesi sourcesi 变为 t a r g e t s i targetsi targetsi 」。

然后遍历 m a t c h I n d e x matchIndex matchIndex 列表,如果 m a t c h I n d e x i ≠ − 1 matchIndexi \ne -1 matchIndexi=−1 ,说明要进行替换,把 t a r g e t s m a t c h I n d e x \[ i ] targetsmatchIndex\[i] targetsmatchIndex\[i] 加入答案,然后 i i i 增加 s o u r c e s m a t c h I n d e x \[ i ] sourcesmatchIndex\[i] sourcesmatchIndex\[i] 的长度;否则说明无需替换,把 s i si si 加入答案,然后 i i i 加一。

cpp 复制代码
class Solution {
public:
    string findReplaceString(string s, vector<int>& indices, vector<string>& sources, vector<string>& targets) {
        string ans;
        int k = indices.size(), n = s.size();
        int matchIndex[n];
        memset(matchIndex, -1, sizeof(matchIndex));

        for (int i = 0; i < k; ++i) {
            int sn = sources[i].size();
            bool isMatch = true;
            for (int j = indices[i]; j < indices[i] + sn; ++j) { // j为原串中的下标
                if (sources[i][j - indices[i]] != s[j]) { // 某个字符不同
                    isMatch = false;
                    break;
                }
            } // 如果子串出现在原串的indices[i]处,则记录要用来替换的新串的下标
            if (isMatch) matchIndex[indices[i]] = i;
        }
        for (int i = 0; i < n; ++i) {
            if (matchIndex[i] != -1) { // 要进行替换
                int index = matchIndex[i];
                ans += targets[index];
                i = indices[index] + sources[index].size() - 1; // i要跳转到原串后面
            } else ans.push_back(s[i]);
        }
        return ans;
    }
};

复杂度分析:

  • 时间复杂度: O ( M + N ) O(M+N) O(M+N)
  • 空间复杂度: O ( M + N ) O(M+N) O(M+N)
相关推荐
生态学者6 小时前
Global Change Biology | 森林越“步调一致”,反而越怕干旱?树木生长与叶片活动的同步之谜
大数据·人工智能·算法·r语言·微信公众平台
lsswear7 小时前
Agent 框架新手入门与实战部署指南
大数据·人工智能·算法
Data analyse4568 小时前
rnweb 回放数据量太大怎么办?分片存储与断点续传的实现思路
前端·网络·算法·数据分析
Navigator_Z10 小时前
LeetCode //C - 1293. Shortest Path in a Grid with Obstacles Elimination
c语言·算法·leetcode
Nil20810 小时前
leetcode 64最小路径和
算法·leetcode·职场和发展
光影少年10 小时前
AI Agent、自动化与未来工作
人工智能·算法·架构
牧羊人.33310 小时前
计算机视觉基础 第16章|EigenFace,FisherFace,LBPH传统人脸识别算法
人工智能·算法·计算机视觉
Nil20811 小时前
leetcode 72编辑距离
算法·leetcode·职场和发展
神工坊11 小时前
技术分享︱SIMFORGE HSF® 网格加密与热点加速技术实践
算法·hpc·网格·cae·工程仿真·数值引擎·samr
Nil20811 小时前
leetcode 136只出现一次的数字
leetcode·哈希算法·散列表