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

来源:力扣(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:

1

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

示例 2:
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] 仅由小写英文字母组成

方法一:按照下标排序 + 模拟

思路与算法

我们直接按照题目的要求进行模拟即可。

首先我们根据数组 indices,将所有的替换操作进行升序排序。在这一步中,同时对 indices,sources,targets 这三个数组进行排序较为困难,我们可以使用一个长度(记为 m)与它们相同的数组 ops,存储 0 到 m − 1 这 m 个下标,随后对 ops 本身按照 indices 作为第一关键字进行排序即可。

在排序完成后,我们就可以遍历给定的字符串 s 进行操作了。我们使用另一个指针 pt 指向 ops 的首个元素,表示当前需要进行的操作。当我们遍历到第 i 个字符时,我们首先不断往右移动 pt,直到其移出边界,或者第 ops[pt] 个操作的下标不小于 iii。此时,会有如下的两种情况:

  • 如果这个下标大于 i,说明不存在下标为 i 的操作。我们可以直接将第 i 个字符放入答案中;
  • 如果这个下标等于 i,说明存在下标为 i 的操作。我们将 s 从位置 i 开始的长度与 sources[ops[i]] 的子串与 sources[ops[i]] 进行比较:
    • 如果相等,那么替换操作成功,我们将 targets[ops[i]] 放入答案中。由于替换操作不可能重叠,因此我们可以直接跳过 sources[ops[i]] 长度那么多数量的字符;
    • 否则,替换操作失败,我们可以直接将第 i 个字符放入答案中。

需要注意的是,题目中只保证了成功的替换操作不会重叠,而不保证失败的替换操作不会重叠。因此当这个下标等于 i 时,可能会有多个替换操作需要进行尝试,即我们需要不断往右移动 pt,直到其移出边界,或者第 ops[pt] 个操作的下标严格大于 i。遍历到的替换操作需要依次进行尝试,如果其中一个成功,那么剩余的不必尝试,可以直接退出。

代码:

class Solution {
public:string findReplaceString(string s, vector<int>& indices, vector<string>& sources, vector<string>& targets) {int n = s.size(), m = indices.size();vector<int> ops(m);iota(ops.begin(), ops.end(), 0);sort(ops.begin(), ops.end(), [&](int i, int j) { return indices[i] < indices[j]; });string ans;int pt = 0;for (int i = 0; i < n;) {while (pt < m && indices[ops[pt]] < i) {++pt;}bool succeed = false;while (pt < m && indices[ops[pt]] == i) {if (s.substr(i, sources[ops[pt]].size()) == sources[ops[pt]]) {succeed = true;break;}++pt;}if (succeed) {ans += targets[ops[pt]];i += sources[ops[pt]].size();}else {ans += s[i];++i;}}return ans;}
};

时间 0ms 击败 100.00%使用 C++ 的用户
内存 9.95mb 击败 88.18%使用 C++ 的用户
复杂度分析

  • 时间复杂度:O(n+mlog⁡m+ml),其中 n 是字符串 s 的长度,m 是数组 indices 的长度,l 是数组 sources 和 targets 中字符串的平均长度。
    - 排序需要的时间为 O(mlog⁡m);
    - 在使用双指针进行遍历的过程中,遍历字符串需要的时间为 O(n),遍历数组 ops 需要的时间为 O(m),在最坏情况下需要尝试每一个替换操作,比较和构造最终答案需要的时间为 O(ml)。
    相加即可得到总时间复杂度 O(n+mlogm+ml)。
  • 空间复杂度:O(n + ml)。
    - 数组 ops 需要的空间为 O(m);
    - 排序需要的栈空间为 O(log⁡m);
    - 在替换操作中进行比较时,如果使用的语言支持无拷贝的切片操作,那么需要的空间为 O(1),否则为 O(l);
    - 在构造最终答案时,如果使用的语言支持带修改的字符串,那么需要的空间为 O(1)(不考虑最终答案占用的空间),否则需要 O(n + ml) 的辅助空间。
    对于不同语言,上述需要的空间会有所变化。这里取每一种可能的最大值,相加即可得到总空间复杂度 O(n + ml)。

方法二:哈希表 + 模拟

思路与算法

我们也可以将方法一中的数组 ops 换成哈希映射,其中的键表示字符串中的下标,值是一个数组,存储了所有操作该下标的操作编号。我们只需要对数组 indices 进行一次遍历,就可以得到这个哈希表。

在这之后,当我们对字符串 s 进行遍历时,如果遍历到位置 i,那么哈希表中键 i 对应的数组,就是所有对位置 i 进行的操作。我们使用与方法一相同的方法处理这些操作即可。

代码:

class Solution {
public:string findReplaceString(string s, vector<int>& indices, vector<string>& sources, vector<string>& targets) {int n = s.size(), m = indices.size();unordered_map<int, vector<int>> ops;for (int i = 0; i < m; ++i) {ops[indices[i]].push_back(i);}string ans;for (int i = 0; i < n;) {bool succeed = false;if (ops.count(i)) {for (int pt: ops[i]) {if (s.substr(i, sources[pt].size()) == sources[pt]) {succeed = true;ans += targets[pt];i += sources[pt].size();break;}}}if (!succeed) {ans += s[i];++i;}}return ans;}
};

时间 0ms 击败 100.00%使用 C++ 的用户
内存 10.12mb 击败 59.09%使用 C++ 的用户
复杂度分析

  • 时间复杂度:O(n+ml),其中 n 是字符串 s 的长度,m 是数组 indices 的长度,l 是数组 sources 和 targets 中字符串的平均长度。
  • 空间复杂度:O(n+ml)。
    author:力扣官方题解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/67498.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ES中倒排索引机制

在ES的倒排索引机制中有四个重要的名词&#xff1a;Term、Term Dictionary、Term Index、Posting List。 Term&#xff08;词条&#xff09;&#xff1a;词条是索引里面最小的存储和查询单元。一段文本经过分析器分析以后就会输出一串词条。一般来说英文语境中词条是一个单词&a…

nodejs+vue+elementui医院电子病历管理系统5a4x5

此系统任何人都可以使用&#xff0c;哪怕对代码完全不懂&#xff0c;只会电脑的基础操作并且安装这几款软件就可以对本系统进行操作&#xff0c;实现了人员使用方面的自由&#xff0c;不必有过多的限制。 语言 node.js 框架&#xff1a;Express 前端:Vue.js 数据库&#xff1a;…

Http缓存机制

真是一个庞大的话题 // HttpResponse HTTP/1.1 200 OK Content-Type: text/html Content-Length: 1024 Date: Tue, 22 Feb 2022 22:22:22 GMT -->请求返回的最新时间 // &#xff08;这个时间居然是服务器返回的,那如果发生服务器在DatemaxAge时间之前Response更新了怎么办…

HTTP--Request详解

请求消息数据格式 请求行 请求方式 请求url 请求协议/版本 GET /login.html HTTP/1.1 请求头 客户端浏览器告诉服务器一些信息 请求头名称: 请求头值 常见的请求头&#xff1a; User-Agent&#xff1a;浏览器告诉服务器&#xff0c;我访问你使用的浏览器版本信息 可…

论文复现--关于多视角动作捕捉工具箱 --XRMoCap的研究

分类&#xff1a;动作捕捉 github地址&#xff1a;https://github.com/openxrlab/xrmocap 所需环境&#xff1a; Ubuntu18.04&#xff0c;conda22.9.0&#xff0c;CUDA11.4 目录 环境配置 环境配置 conda create -n XRmocap python3.7 -y conda activate XRmocap# install ffm…

考研408 | 【计算机网络】 传输层

导图 传输层的功能 传输层的两个协议 传输层的寻址与端口 UDP协议 UDP的主要特点 UDP首部格式&#xff1a; UDP校验&#xff1a; TCP协议 TCP协议的特点 TCP报文段首部格式 TCP连接管理 TCP的连接建立 SYN洪泛攻击 TCP的连接释放 TCP可靠传输 序号&#xff1a; 确认&#xff1…

【Vue-Router】使用 prams 路由传参失效

报错信息&#xff1a; [Vue Router warn]: Discarded invalid param(s) “name”, “price”, “id” when navigating. list.json {"data": [{"name": "面","price":300,"id": 1},{"name": "水",&quo…

Algorithem Review 5.2 图论

网络流 设源点为 s s s&#xff0c;汇点为 t t t&#xff0c;每条边 e e e 的流量上限为 c ( e ) c(e) c(e)&#xff0c;流量为 f ( e ) f(e) f(e)。割 指对于某一顶点集合 P ⊂ V P \subset V P⊂V&#xff0c;从 P P P 出发指向 P P P 外部的那些原图中的边的集合&a…

OBD接口引脚定义

汽车的OBD接口引脚定义分配如下图所示&#xff0c;OBD接口共有16个引脚&#xff08;可参考 ISO 15031-3&#xff09;。 1、引脚1,3,8,9,11,12,13 引脚1,3,8,9,11,12,13由主机厂进行分配。 2、引脚2 如果车辆中使用SAE J1850 10,4 VPW&#xff08;可变脉冲&#xff09;来提供…

智能设备管理系统对企业设备管理效果有作用吗?

智能设备管理系统对企业设备管理效果具有显著的作用和积极的影响。它可以提高设备管理的效率、准确性和可靠性&#xff0c;帮助企业降低运营成本、提高生产效率&#xff0c;并为企业提供更好的决策支持。以下是智能设备管理系统对企业设备管理效果的几个方面影响&#xff1a; …

ChatGPT能代替搜索引擎吗?ChatGPT和搜索引擎有什么区别?

ChatGPT和搜索引擎是两种在信息获取和交流中常用的工具&#xff0c;ChatGPT是一种基于人工智能技术的聊天机器人&#xff0c;而搜索引擎是一种在互联网上搜索信息的工具。尽管它们都是依托互联网与信息获取和交流有关&#xff0c;部分功能重合&#xff0c;但在很多方面存在着明…

简单谈谈 EMP-SSL:自监督对比学习的一种极简主义风

论文链接&#xff1a;https://arxiv.org/pdf/2304.03977.pdf 代码&#xff1a;https://github.com/tsb0601/EMP-SSL 其他学习链接&#xff1a;突破自监督学习效率极限&#xff01;马毅、LeCun联合发布EMP-SSL&#xff1a;无需花哨trick&#xff0c;30个epoch即可实现SOTA 主要…