LeetCode-Py第1300-1399题详解:前缀和与差分算法应用

在算法面试中,前缀和与差分算法是解决数组区间问题的高效工具,能够将暴力解法的O(n²)复杂度优化至O(n)。本文通过LeetCode第1300-1399题中的典型例题,详细讲解这两类算法的实战应用,帮助读者掌握区间查询与修改的核心技巧。

【免费下载链接】LeetCode-Py ⛽️「算法通关手册」:超详细的「算法与数据结构」基础讲解教程,从零基础开始学习算法知识,800+ 道「LeetCode 题目」详细解析,200 道「大厂面试热门题目」。 【免费下载链接】LeetCode-Py 项目地址: https://gitcode.com/gh_mirrors/le/LeetCode-Py

算法基础:前缀和与差分的数学原理

前缀和(Prefix Sum)通过预处理数组构建前缀和数组,实现区间和的O(1)查询;差分(Difference Array)则通过构造差分数组,将区间修改转化为单点操作。两者结合可高效解决区间统计、范围更新类问题。

前缀和的定义与性质

对于数组arr,其前缀和数组prefix定义为:

prefix[0] = 0
prefix[i] = arr[0] + arr[1] + ... + arr[i-1]

则区间[l, r]的和为prefix[r+1] - prefix[l]

差分的定义与性质

对于数组arr,其差分数组diff定义为:

diff[0] = arr[0]
diff[i] = arr[i] - arr[i-1] (i > 0)

对区间[l, r]增加val时,只需执行diff[l] += valdiff[r+1] -= val,最后通过前缀和还原数组。

典型例题解析

1310. 子数组异或查询(前缀异或应用)

题目链接docs/solutions/1300-1399/xor-queries-of-a-subarray.md

核心思路:异或运算具有自反性(x^x=0)和交换律,适合构建前缀异或数组。设prefix_xor[i]为前i个元素的异或结果,则区间[l, r]的异或值为prefix_xor[r+1] ^ prefix_xor[l]

代码实现

def xorQueries(arr, queries):
    n = len(arr)
    prefix_xor = [0] * (n + 1)
    for i in range(n):
        prefix_xor[i+1] = prefix_xor[i] ^ arr[i]
    
    res = []
    for l, r in queries:
        res.append(prefix_xor[r+1] ^ prefix_xor[l])
    return res

复杂度分析:预处理O(n),查询O(1),整体O(n + q)(q为查询次数)。

1343. 大小为K且平均值大于等于阈值的子数组数目(滑动窗口实现)

题目链接docs/solutions/1300-1399/number-of-sub-arrays-of-size-k-and-average-greater-than-or-equal-to-threshold.md

核心思路:转化为区间和问题,需满足sum(arr[l..r]) >= k * threshold。使用固定窗口滑动,维护窗口和并实时判断。

代码实现

def numOfSubarrays(arr, k, threshold):
    target = k * threshold
    window_sum = sum(arr[:k])
    count = 1 if window_sum >= target else 0
    
    for i in range(k, len(arr)):
        window_sum += arr[i] - arr[i-k]
        if window_sum >= target:
            count += 1
    return count

算法对比:前缀和解法需O(n)空间,滑动窗口优化为O(1)空间,适用于大数据量场景。

进阶应用:前缀和与双指针结合

1358. 包含所有三种字符的子字符串数目(滑动窗口+计数)

题目链接docs/solutions/1300-1399/number-of-substrings-containing-all-three-characters.md

核心思路:使用不定长滑动窗口记录字符出现次数,当窗口包含a、b、c时,收缩左边界并统计有效子串数量。

代码实现

def numberOfSubstrings(s):
    count = {'a':0, 'b':0, 'c':0}
    left = 0
    res = 0
    
    for right in range(len(s)):
        count[s[right]] += 1
        
        while all(v > 0 for v in count.values()):
            res += len(s) - right
            count[s[left]] -= 1
            left += 1
    return res

复杂度分析:时间O(n),空间O(1),每个字符最多被访问两次。

实战技巧与避坑指南

  1. 边界处理:前缀和数组多开一个空间(prefix[0] = 0),避免区间计算时的越界判断。
  2. 数据类型:处理大数组时注意整数溢出,Python无需担心但其他语言需使用long类型。
  3. 算法选择
    • 静态区间查询 → 前缀和
    • 动态区间修改 → 差分
    • 定长区间统计 → 滑动窗口

相关题目推荐

题目编号题目名称算法类型
1300转变数组后最接近目标值的数组和二分查找+前缀和
1310子数组异或查询前缀异或
1343大小为K且平均值大于等于阈值的子数组数目滑动窗口
1358包含所有三种字符的子字符串数目不定长滑动窗口

完整题解可参考:docs/solutions/1300-1399/index.md

总结与升华

前缀和与差分算法是处理数组区间问题的"多功能工具",通过空间换时间的策略,将复杂的区间操作转化为简单的数组访问。掌握这些技巧不仅能应对LeetCode中等难度题目,更为解决高频面试题奠定基础。建议结合docs/01_array/01_15_array_two_pointers.md中的双指针技巧进行综合练习,提升算法组合应用能力。

关注后续系列文章,我们将深入讲解树状数组、线段树等高级数据结构,进一步拓展区间问题的解决方案。收藏本文,算法进阶不迷路!

【免费下载链接】LeetCode-Py ⛽️「算法通关手册」:超详细的「算法与数据结构」基础讲解教程,从零基础开始学习算法知识,800+ 道「LeetCode 题目」详细解析,200 道「大厂面试热门题目」。 【免费下载链接】LeetCode-Py 项目地址: https://gitcode.com/gh_mirrors/le/LeetCode-Py

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值