前缀和与差分

前缀和

一维前缀和

以leecode 区域和检索,数组不可变为例

题目描述

给定一个整数数组  nums,处理以下类型的多个查询:

计算索引 left 和 right (包含 left 和 right)之间的 nums 元素的 和 ,其中 left <= right
实现 NumArray 类:

NumArray(int[] nums) 使用数组 nums 初始化对象
int sumRange(int i, int j) 返回数组 nums 中索引 left 和 right 之间的元素的 总和 ,包含 left 和 right 两点(也就是 nums[left] + nums[left + 1] + ... + nums[right] )


 示例 1:

输入:
["NumArray", "sumRange", "sumRange", "sumRange"]
[[[-2, 0, 3, -5, 2, -1]], [0, 2], [2, 5], [0, 5]]
输出:
[null, 1, -1, -3]

解释:
NumArray numArray = new NumArray([-2, 0, 3, -5, 2, -1]);
numArray.sumRange(0, 2); // return 1 ((-2) + 0 + 3)
numArray.sumRange(2, 5); // return -1 (3 + (-5) + 2 + (-1)) 
numArray.sumRange(0, 5); // return -3 ((-2) + 0 + 3 + (-5) + 2 + (-1))

参考代码

public class NumArray {
    private int[]qzh=null;
    public NumArray(int[] nums) {
    this.qzh=new int[nums.length+1];
    for(int i=1;i<qzh.length;i++) {
        qzh[i]=qzh[i-1]+nums[i-1];
    }
    }
    
    public int sumRange(int left, int right) {
        return qzh[right+1]-qzh[left];
    }
}

二维前缀和

以leecode 二维区域和检索 - 矩阵不可变为例

题目描述

给定一个二维矩阵 matrix,以下类型的多个请求:

计算其子矩形范围内元素的总和,该子矩阵的 左上角 为 (row1, col1) ,右下角 为 (row2, col2) 。
实现 NumMatrix 类:

NumMatrix(int[][] matrix) 给定整数矩阵 matrix 进行初始化
int sumRegion(int row1, int col1, int row2, int col2) 返回 左上角 (row1, col1) 、右下角 (row2, col2) 所描述的子矩阵的元素 总

输入: 
["NumMatrix","sumRegion","sumRegion","sumRegion"]
[[[[3,0,1,4,2],[5,6,3,2,1],[1,2,0,1,5],[4,1,0,1,7],[1,0,3,0,5]]],[2,1,4,3],[1,1,2,2],[1,2,2,4]]
输出: 
[null, 8, 11, 12]

解释:
NumMatrix numMatrix = new NumMatrix([[3,0,1,4,2],[5,6,3,2,1],[1,2,0,1,5],[4,1,0,1,7],[1,0,3,0,5]]);
numMatrix.sumRegion(2, 1, 4, 3); // return 8 (红色矩形框的元素总和)
numMatrix.sumRegion(1, 1, 2, 2); // return 11 (绿色矩形框的元素总和)
numMatrix.sumRegion(1, 2, 2, 4); // return 12 (蓝色矩形框的元素总和)

参考代码

class NumMatrix {
    public int[][] matrix=null;
    public int [][]ewqzh=null;
    public NumMatrix(int[][] matrix) {
     this.matrix=matrix;
     ewqzh=new int[matrix.length+1][matrix[0].length+1];
     //填充二维前缀和
     for(int i=0;i<matrix.length;i++) {
         for(int j=0;j<matrix[0].length;j++) {
             ewqzh[i+1][j+1]=ewqzh[i][j+1]+ewqzh[i+1][j]+matrix[i][j]-ewqzh[i][j];
         }
     }
    }
    
    public int sumRegion(int row1, int col1, int row2, int col2) {
      return ewqzh[row2+1][col2+1]-ewqzh[row2+1][col1]-ewqzh[row1][col2+1]+ewqzh[row1][col1];
    }
}

 

差分

一维差分

以leecode航班预订统计为例

题目描述

这里有 n 个航班,它们分别从 1 到 n 进行编号。

有一份航班预订表 bookings ,表中第 i 条预订记录 bookings[i] = [firsti, lasti, seatsi] 意味着在从 firsti 到 lasti (包含 firsti 和 lasti )的 每个航班 上预订了 seatsi 个座位。

请你返回一个长度为 n 的数组 answer,里面的元素是每个航班预定的座位总数。

 

示例1

输入:bookings = [[1,2,10],[2,3,20],[2,5,25]], n = 5
输出:[10,55,45,25,25]
解释:
航班编号        1   2   3   4   5
预订记录 1 :   10  10
预订记录 2 :       20  20
预订记录 3 :       25  25  25  25
总座位数:      10  55  45  25  25
因此,answer = [10,55,45,25,25]

参考代码

class Solution {
    public int[] corpFlightBookings(int[][] bookings, int n) {
       int cf[]=new int[n];
       for(int[]booking:bookings) {
           int start=booking[0];
           int end=booking[1];
           int zuoWei=booking[2];
           cf[start-1]+=zuoWei;
           if(end<n) {
               cf[end]-=zuoWei;
           }
       }
       for(int i=1;i<n;i++) {
           cf[i]+=cf[i-1];
       }
       return cf;
    }
}

 

 

posted @ 2022-04-13 17:54  lzstar-A2  阅读(11)  评论(0编辑  收藏  举报