刷题使我快乐,满脸开心.jpg

  • 来源:力扣(LeetCode)
  • 链接:https://leetcode.cn/problems/find-and-replace-in-string/
  • 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题目

你会得到一个字符串 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] 仅由小写英文字母组成

思路

  • 遍历并确认是否需要替换这里,开始我傻傻自己实现了一个,看了题解才意识到可以使用 strings.HasPrefix 这个内置函数,这一点在刷题里并不重要,但是在工作中,尤其是作为一个业务工程师,这个思维还是需要有的,莫要重复造轮子,除非不合适
  • 查找替换部分需要注意的就是,targets中的字符串并不一定长度和sources匹配,所以为了不影响原本字符串中的下标索引,需要拼结果时再插入,这也就是题目中为何要求“所有替换操作必须同时发生”。

代码

func findReplaceString(s string, indices []int, sources, targets []string) string {
    n := len(s)
    replaceStr := make([]string, n)
    replaceLen := make([]int, n)
    for i, indice := range indices {
        if strings.HasPrefix(s[indice:], sources[i]) {
            replaceStr[indice] = targets[i]
            replaceLen[indice] = len(sources[i])
        }
    }

    res := ""
    for i := 0; i < n; {
        if replaceStr[i] == "" {
            res += string(s[i])
            i++
        } else {
            res += replaceStr[i]
            i += replaceLen[i]
        }
    }
    return res
}