同向双指针(下)
摘要
- 数组和字符串上的同向双指针
- 滑动窗口求和
- K次替换后最长的重复字符子串
- 快慢指针算法
- 链表求交、链表求环
- 链表中位点
604 · 滑动窗口内数的和
nums = [1,2,7,8,5], k = 3
求出数组中所有连续 k 个数之和
返回 [10,17,20]
func WinSum(nums []int, k int) []int {
res := []int{}
if len(nums) == 0 || len(nums) < k {
return res
}
j := 0
windowSum := 0
for i := 0; i < len(nums); i++ {
for j < len(nums) && j-i < k {
windowSum += nums[j]
j++
}
if j-i == k {
res = append(res, windowSum)
}
windowSum -= nums[i]
}
return res
}
1246 · 替换后的最长重复字符
允许替换字符串中的字符 K 次
问替换之后,最长的重复字符有多长
s = ABABA, k = 2
替换 B 到 A 可以获得长度为 5 的全 A 子串
/**
* @param s: a string
* @param k: a integer
* @return: return a integer
*/
func CharacterReplacement(s string, k int) int {
counter := make(map[byte]int)
ans := 0
// j 指向满足条件的子字符串的后面一个位置
j := 0
maxFreq := 0
for i := 0; i < len(s); i++ {
// 找到 i ~ j-1 这一段是最长的以i开头的满足
// 不超过 k 次替换的 substring
for j < len(s) && j-i-maxFreq <= k {
counter[s[j]]++
maxFreq = max(maxFreq, counter[s[j]])
j++
}
if j-i-maxFreq > k {
// i ~ j-1 的 substring 需要 k+1
// i ~ j-2 的 substring 只需要 k 次替换
ans = max(ans, j-2-i+1)
} else {
ans = max(ans, j-i)
}
counter[s[i]]--
maxFreq = 0
for _, cnt := range counter {
if cnt > maxFreq {
maxFreq = cnt
}
}
}
return ans
}
数组和字符串上的同向双指针总结
数组和字符串的问题有很多题都是和双指针,特别是同向双指针有关
通常问题让我们求是一段子数组或者子字符串
所以遇到“子数组 SubArray” 和“子字符串 SubString” 就需要往同向双指针思考
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。