【LeetCode精选算法】前缀和专题二

目录

[29. 和为k的子数组(medium)](#29. 和为k的子数组(medium))

[30. 和可被K整除的子数组(medium)](#30. 和可被K整除的子数组(medium))

[31. 连续数组(medium)](#31. 连续数组(medium))

[32. 矩阵区域和(medium)](#32. 矩阵区域和(medium))


29. 和为k的子数组(medium)

题目链接

解题思路

使用哈希表记录前缀和出现的次数。遍历数组,计算当前前缀和 sum,若 sum - k 在哈希表中存在,则累加其出现次数。

Java 代码

java 复制代码
class Solution {
    public int subarraySum(int[] nums, int k) {
        Map<Integer, Integer> hash = new HashMap<>();
        hash.put(0, 1);
        int sum = 0, ret = 0;
        for (int x : nums) {
            sum += x;
            ret += hash.getOrDefault(sum - k, 0);
            hash.put(sum, hash.getOrDefault(sum, 0) + 1);
        }
        return ret;
    }
}

30. 和可被K整除的子数组(medium)

题目链接

解题思路

利用同余定理,若 (sum[i] - sum[j]) % K == 0,则 sum[i] % K == sum[j] % K。使用哈希表记录每个余数出现的次数。

Java 代码

java 复制代码
class Solution {
    public int subarraysDivByK(int[] nums, int k) {
        Map<Integer, Integer> hash = new HashMap<>();
        hash.put(0 % k, 1);
        int sum = 0, ret = 0;
        for (int x : nums) {
            sum += x;
            int r = (sum % k + k) % k;
            ret += hash.getOrDefault(r, 0);
            hash.put(r, hash.getOrDefault(r, 0) + 1);
        }
        return ret;
    }
}

31. 连续数组(medium)

题目链接

解题思路

0 视为 -1,问题转化为寻找和为 0 的最长子数组。使用哈希表记录每个前缀和第一次出现的位置。

Java 代码

java 复制代码
class Solution {
    public int subarraysDivByK(int[] nums, int k) {
        Map<Integer, Integer> hash = new HashMap<>();
        hash.put(0 % k, 1);
        int sum = 0, ret = 0;
        for (int x : nums) {
            sum += x;
            int r = (sum % k + k) % k;
            ret += hash.getOrDefault(r, 0);
            hash.put(r, hash.getOrDefault(r, 0) + 1);
        }
        return ret;
    }
}

32. 矩阵区域和(medium)

题目链接

解题思路

使用二维前缀和,对于每个 (i,j),计算其周围 k 范围内的区域和。注意边界处理。

Java 代码

java 复制代码
class Solution {
    public int findMaxLength(int[] nums) {
        Map<Integer, Integer> hash = new HashMap<>();
        hash.put(0, -1);
        int sum = 0, ret = 0;
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i] == 0 ? -1 : 1;
            if (hash.containsKey(sum)) {
                ret = Math.max(ret, i - hash.get(sum));
            } else {
                hash.put(sum, i);
            }
        }
        return ret;
    }
}
相关推荐
naruto_lnq18 小时前
分布式系统安全通信
开发语言·c++·算法
Jasmine_llq18 小时前
《P3157 [CQOI2011] 动态逆序对》
算法·cdq 分治·动态问题静态化+双向偏序统计·树状数组(高效统计元素大小关系·排序算法(预处理偏序和时间戳)·前缀和(合并单个贡献为总逆序对·动态问题静态化
爱吃rabbit的mq19 小时前
第09章:随机森林:集成学习的威力
算法·随机森林·集成学习
(❁´◡`❁)Jimmy(❁´◡`❁)19 小时前
Exgcd 学习笔记
笔记·学习·算法
YYuCChi20 小时前
代码随想录算法训练营第三十七天 | 52.携带研究材料(卡码网)、518.零钱兑换||、377.组合总和IV、57.爬楼梯(卡码网)
算法·动态规划
不能隔夜的咖喱20 小时前
牛客网刷题(2)
java·开发语言·算法
VT.馒头20 小时前
【力扣】2721. 并行执行异步函数
前端·javascript·算法·leetcode·typescript
进击的小头20 小时前
实战案例:51单片机低功耗场景下的简易滤波实现
c语言·单片机·算法·51单片机
咖丨喱1 天前
IP校验和算法解析与实现
网络·tcp/ip·算法
罗湖老棍子1 天前
括号配对(信息学奥赛一本通- P1572)
算法·动态规划·区间dp·字符串匹配·区间动态规划