前缀和与差分

一维数组前缀和与差分

前缀和

核心概念:

前缀和数组 prefix 中,prefix[i] 表示原数组 arr 前 i 个元素的和(arr[0] + arr[1] + ... + arr[i-1])。通过前缀和可快速计算原数组任意区间 [l, r] 的和:sum(l, r) = prefix[r+1] - prefix[l]。跟我们高中学的数列,前n项和类似。

复制代码
import java.util.Scanner;
public class PrefixSumWithInput{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);   
        int n=sc.nextInt();
        int[]arr=new int[n];
        for(int i=0;i<n;i++){
            arr[i]=sc.nextInt();
        }
        // 3. 构建前缀和数组
        int[]prefix=new int[n + 1]; // 前缀和数组长度为 n+1,prefix[0] = 0
        for(int i=0;i<n;i++){
            prefix[i+1]=prefix[i]+arr[i]; // 核心公式:累加前 i 个元素
        }  
        int l=sc.nextInt();
        int r=sc.nextInt();
        if(l<0||r>=n||l>r){
             return;
        }else{ 
            int sum=prefix[r+1]-prefix[l];
            System.out.println(sum);
        }
    }
}
差分

核心概念:

差分是一种前缀和的逆运算,用于高效处理数组的**「区间增减」** 操作。通过构建一个「差分数组」,可以将原本 O (n) 时间复杂度的区间更新,优化到 O (1);最终通过差分数组的前缀和,还原出更新后的原数组(时间复杂度 O (n))原数组:nums0...n-1,差分数组:diff0...n(通常比原数组多一位,避免边界判断)差分数组的前缀和 = 原数组,即 numsi = diff0 + diff1 + ... + diffi。

复制代码
import java.util.Arrays;
public class Difference{
    public static void main(String[]args){
        // 1. 原数组(直接替换为目标数组)
        int[]nums={}; // 此处替换为你的原数组
        int n = nums.length;
        // 2. 构建差分数组(核心公式)
        int[]diff=new int[n+1];
        if(n>0){
            diff[0]=nums[0];
            for(int i=1;i<n;i++){
                diff[i]=nums[i]-nums[i-1];
            }
        }
        // 3. 区间更新(按需添加,格式:[l, r] 加 val,可多个)
        diff[l] += val;
        diff[r + 1] -= val;
        // 4. 还原更新后的数组(前缀和)
        int[] res=new int[n];
        if(n>0){
            res[0]=diff[0];
            for(int i=1;i<n;i++){
                res[i]=res[i-1]+diff[i];
            }
        }
        // 输出结果
         System.out.println(Arrays.toString(res));
    }
}

二维数组的前缀和与差分

前缀和

左+上-左上+自己

复制代码
public class NumMatrix {
    public int[][] sum;

    public NumMatrix(int[][] matrix) {
        int n = matrix.length;
        int m = matrix[0].length;
        sum = new int[n + 1][m + 1];
        for (int a = 1, c = 0; c < n; a++, c++) {
            for (int b = 1, d = 0; d < m; b++, d++) {
                sum[a][b] = matrix[c][d];
            }
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                sum[i][j] += sum[i][j - 1] + sum[i - 1][j] - sum[i - 1][j - 1];
            }
        }
    }

    public int sumRegion(int a, int b, int c, int d) {
        c++;
        d++;
        return sum[c][d] - sum[c][b] - sum[a][d] + sum[a][b];
    }
}
二维差分
复制代码
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int k = sc.nextInt();

        // 差分数组开大一点,防止越界
        int[][] diff = new int[n + 2][m + 2];

        for (int i = 0; i < k; i++) {
            int x1 = sc.nextInt();
            int y1 = sc.nextInt();
            int x2 = sc.nextInt();
            int y2 = sc.nextInt();
            int c = sc.nextInt();

            // 二维差分核心操作
            diff[x1][y1] += c;
            diff[x1][y2 + 1] -= c;
            diff[x2 + 1][y1] -= c;
            diff[x2 + 1][y2 + 1] += c;
        }

        // 求二维前缀和,得到最终矩阵
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                diff[i][j] += diff[i - 1][j] + diff[i][j - 1] - diff[i - 1][j - 1];
                System.out.print(diff[i][j] + " ");
            }
            System.out.println();
        }
    }
}
相关推荐
txxzjmzlh10 小时前
SpringBoot 配置⽂件
java·spring boot·spring
ZhengEnCi10 小时前
模型训练完整流程:从数据准备到模型上线的 10 个关键步骤(全文可跑)
后端·算法
Wang's Blog10 小时前
Java 项目实战: 交友项目 - 搜索附近的功能概述和分析
java·开发语言·交友
骑着蜗牛撵大象32710 小时前
大模型 Agent 的沙箱护栏:gVisor 隔离、出口白名单与审计闭环
java·开发语言·jvm·安全·agent沙箱·gvisor·microvm
独泪了无痕10 小时前
Hutool之LocalDateTimeUtil:让时间间隔操作如虎添翼
java
三无少女指南12 小时前
从这里开始:Java 后端与 AI 工程的三条阅读路线
java·学习路线·ai工程
香蕉大香蕉(06敬畏市场)12 小时前
MySQL 单点详解(07)
java·数据库·mysql·ai·博客·八股
nice_lcj52012 小时前
深入理解 Java 反射:从 Class 对象到方法调用(含性能实测 + 迷你 IOC 实战 + 面试考点)
java·开发语言·后端·面试
骑着蜗牛撵大象32713 小时前
2026 后端 AI 工程化:Spring AI 管调用、MCP 管工具、Agent 内嵌管自治
java·人工智能·后端·spring·ai·可观测性·mcp