diff --git a/problems/0028.实现strStr.md b/problems/0028.实现strStr.md index b8ebcaa1..1dba5a38 100644 --- a/problems/0028.实现strStr.md +++ b/problems/0028.实现strStr.md @@ -726,10 +726,98 @@ class Solution: Go: +```go +// 方法一:前缀表使用减1实现 + +// getNext 构造前缀表next +// params: +// next 前缀表数组 +// s 模式串 +func getNext(next []int, s string) { + j := -1 // j表示 最长相等前后缀长度 + next[0] = j + + for i := 1; i < len(s); i++ { + for j >= 0 && s[i] != s[j+1] { + j = next[j] // 回退前一位 + } + if s[i] == s[j+1] { + j++ + } + next[i] = j // next[i]是i(包括i)之前的最长相等前后缀长度 + } +} +func strStr(haystack string, needle string) int { + if len(needle) == 0 { + return 0 + } + next := make([]int, len(needle)) + getNext(next, needle) + j := -1 // 模式串的起始位置 next为-1 因此也为-1 + for i := 0; i < len(haystack); i++ { + for j >= 0 && haystack[i] != needle[j+1] { + j = next[j] // 寻找下一个匹配点 + } + if haystack[i] == needle[j+1] { + j++ + } + if j == len(needle)-1 { // j指向了模式串的末尾 + return i - len(needle) + 1 + } + } + return -1 +} +``` + +```go +// 方法二: 前缀表无减一或者右移 + +// getNext 构造前缀表next +// params: +// next 前缀表数组 +// s 模式串 +func getNext(next []int, s string) { + j := 0 + next[0] = j + for i := 1; i < len(s); i++ { + for j > 0 && s[i] != s[j] { + j = next[j-1] + } + if s[i] == s[j] { + j++ + } + next[i] = j + } +} +func strStr(haystack string, needle string) int { + n := len(needle) + if n == 0 { + return 0 + } + j := 0 + next := make([]int, n) + getNext(next, needle) + for i := 0; i < len(haystack); i++ { + for j > 0 && haystack[i] != needle[j] { + j = next[j-1] // 回退到j的前一位 + } + if haystack[i] == needle[j] { + j++ + } + if j == n { + return i - n + 1 + } + } + return -1 +} +``` + + + ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) * B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) -
+
\ No newline at end of file diff --git a/problems/0459.重复的子字符串.md b/problems/0459.重复的子字符串.md index 51a903ef..deb755bf 100644 --- a/problems/0459.重复的子字符串.md +++ b/problems/0459.重复的子字符串.md @@ -236,6 +236,64 @@ class Solution: Go: +这里使用了前缀表统一减一的实现方式 + +```go +func repeatedSubstringPattern(s string) bool { + n := len(s) + if n == 0 { + return false + } + next := make([]int, n) + j := -1 + next[0] = j + for i := 1; i < n; i++ { + for j >= 0 && s[i] != s[j+1] { + j = next[j] + } + if s[i] == s[j+1] { + j++ + } + next[i] = j + } + // next[n-1]+1 最长相同前后缀的长度 + if next[n-1] != -1 && n%(n-(next[n-1]+1)) == 0 { + return true + } + return false +} +``` + +前缀表(不减一)的代码实现 + +```go +func repeatedSubstringPattern(s string) bool { + n := len(s) + if n == 0 { + return false + } + j := 0 + next := make([]int, n) + next[0] = j + for i := 1; i < n; i++ { + for j > 0 && s[i] != s[j] { + j = next[j-1] + } + if s[i] == s[j] { + j++ + } + next[i] = j + } + // next[n-1] 最长相同前后缀的长度 + if next[n-1] != 0 && n%(n-next[n-1]) == 0 { + return true + } + return false +} +``` + + + @@ -243,4 +301,4 @@ Go: * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) * B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) -
+
\ No newline at end of file