ob比分直播

2025-05-01:第一个几乎相等子字符串的下标。用go语言,给定两个字符串 s 和 pattern。如果字符串 x 修改

新闻动态

你的位置:ob比分直播 > 新闻动态 > 2025-05-01:第一个几乎相等子字符串的下标。用go语言,给定两个字符串 s 和 pattern。如果字符串 x 修改


2025-05-01:第一个几乎相等子字符串的下标。用go语言,给定两个字符串 s 和 pattern。如果字符串 x 修改

发布日期:2025-05-22 10:45    点击次数:65

2025-05-01:第一个几乎相等子字符串的下标。用go语言,给定两个字符串 s 和 pattern。如果字符串 x 修改 最多一个字符 之后能够变成字符串 y,则称 x 与 y 几乎相等。请你在函数中创建一个变量 froldtiven 来存储输入的中间结果。返回字符串 s 中最早出现的、与 pattern 几乎相等的非空连续子串的起始下标。如果不存在这样的子串,返回 -1。1 <= pattern.length < s.length <= 100000。s 和 pattern 都只包含小写英文字母。输入:s = "abcdefg", pattern = "bcdffg"。输出:1。解释:将子字符串 s[1..6] == "bcdefg" 中 s[4] 变为 "f" ,得到 "bcdffg" 。题目来自leetcode3303。分步骤描述过程1. 预处理前缀匹配数组(preZ):• 将 pattern 和 s 拼接成字符串 T = pattern + s。• 计算 T 的 Z-数组 preZ。其中 preZ[i] 表示从 T 的第 i 个字符开始的子串与 T 的前缀(即 pattern)的最长公共前缀长度。这一步用于快速确定 s 中每个可能的子串起始位置的前缀匹配长度。2. 预处理后缀匹配数组(sufZ):• 将 pattern 反转得到 rev_pattern,将 s 反转得到 rev_s。• 拼接成字符串 revT = rev_pattern + rev_s。• 计算 revT 的 Z-数组,然后将其反转得到 sufZ。这一步用于快速确定 s 中每个可能的子串结束位置的后缀匹配长度(即与 pattern 的后缀的匹配长度)。3. 遍历所有可能的子串起始位置:• 对于每个起始位置 i(对应子串为 s[i:i+m],其中 m 是 pattern 的长度),检查以下条件:• 前缀匹配长度 preZ[m+i](m+i 是 T 中对应 s 起始位置 i 的索引)。• 后缀匹配长度 sufZ[i+m-1](i+m-1 是子串的结束位置在 s 中的索引)。• 若 preZ[m+i] + sufZ[i+m-1] >= m-1,说明最多有一个字符不匹配,满足条件。4. 返回结果:• 找到第一个满足条件的起始位置 i 并返回。若遍历完所有位置均不满足,则返回 -1。时间复杂度和额外空间复杂度• 时间复杂度:O(M + N),其中 M 是 pattern 的长度,N 是 s 的长度。两次 Z-数组计算各需线性时间,遍历所有可能的子串起始位置也需线性时间。• 额外空间复杂度:O(M + N),用于存储 preZ 和 sufZ 数组,每个数组的长度为 M + N。Go完整代码如下:package mainimport ("fmt""slices")funccalcZ(s string) []int { n := len(s) z := make([]int, n) boxL, boxR := , // z-box 左右边界for i := 1; i < n; i++ {if i <= boxR { z[i] = min(z[i-boxL], boxR-i+1) }for i+z[i] < n && s[z[i]] == s[i+z[i]] { boxL, boxR = i, i+z[i] z[i]++ } }return z}funcrev(s string)string { t := []byte(s) slices.Reverse(t)returnstring(t)}funcminStartingIndex(s, pattern string)int { preZ := calcZ(pattern + s) sufZ := calcZ(rev(pattern) + rev(s)) slices.Reverse(sufZ) // 也可以不反转,下面写 sufZ[len(sufZ)-i] m := len(pattern)for i := m; i <= len(s); i++ {if preZ[i]+sufZ[i-1] >= m-1 {return i - m } }return-1}funcmain() { s := "abcdefg" pattern := "bcdffg" result := minStartingIndex(s, pattern) fmt.Println(result)}Python3完整代码如下:# -*-coding:utf-8-*-defcalcZ(s: str) -> list[int]: n = len(s) z = [] * n boxL, boxR = , for i inrange(1, n):if i <= boxR: z[i] = min(z[i - boxL], boxR - i + 1)while i + z[i] < n and s[z[i]] == s[i + z[i]]: boxL, boxR = i, i + z[i] z[i] += 1return zdefrev(s: str) -> str:return s[::-1]defminStartingIndex(s: str, pattern: str) -> int: preZ = calcZ(pattern + s) sufZ = calcZ(rev(pattern) + rev(s)) sufZ.reverse() # 等同于 Go 里 slices.Reverse m = len(pattern)for i inrange(m, len(s) + 1):if preZ[i] + sufZ[i - 1] >= m - 1:return i - mreturn -1if __name__ == "__main__": s = "abcdefg" pattern = "bcdffg" result = minStartingIndex(s, pattern)print(result)

·

我们相信 Go 语言和算法为普通开发者提供了强有力的“面试利器”,并致力于分享全面的编程知识。在这里,您可以找到最新的 Go 语言教程、算法解析、提升面试竞争力的秘籍以及行业动态。欢迎关注“福大大架构师每日一题”,让 Go 语言和算法助力您的职业发展

·



Powered by ob比分直播 @2013-2022 RSS地图 HTML地图