首页 > 其他分享 >leetcode-前缀和数组&差分数组

leetcode-前缀和数组&差分数组

时间:2023-06-26 11:55:30浏览次数:36  
标签:sumArr 前缀 nums int NumArray 差分 数组 leetcode

前缀和数组:

前缀和技巧适用于快速、频繁地计算一个索引区间内的元素之和。(仅仅适用于原数组不变的情况,如果原数组经常修改,则需要考虑差分数组。)

模版如下:

class PrefixSum {
    // 前缀和数组
    private int[] preSum;

    /* 输入一个数组,构造前缀和 */
    public PrefixSum(int[] nums) {
        // preSum[0] = 0,便于计算累加和
        preSum = new int[nums.length + 1];
        // 计算 nums 的累加和
        for (int i = 1; i < preSum.length; i++) {
            preSum[i] = preSum[i - 1] + nums[i - 1];
        }
    }
    
    /* 查询闭区间 [left, right] 的累加和 */
    public int sumRange(int left, int right) {
        return preSum[right + 1] - preSum[left];
    }
}

 

 

看两道例题就清楚了:

1. 303. 区域和检索 - 数组不可变 - 力扣(LeetCode)

 由于要频繁计算某个区间内的元素之和,暴力解法复杂度太大,显然前缀和比较合适,代码如下:

class NumArray {
    //前缀和数组
    int[] sumArr;

    public NumArray(int[] nums) {
        sumArr = new int[nums.length + 1];
        for(int i = 1; i < sumArr.length; i++){
            sumArr[i] = sumArr[i - 1] + nums[i - 1];
        }
    }
    
    public int sumRange(int left, int right) {
        //计算[i, j]范围内的和是用sumArr[j + 1] - sumArr[i]计算
        return sumArr[right + 1] - sumArr[left];
    }
}

/**
 * Your NumArray object will be instantiated and called as such:
 * NumArray obj = new NumArray(nums);
 * int param_1 = obj.sumRange(left,right);
 */

 

2. 304. 二维区域和检索 - 矩阵不可变 - 力扣(LeetCode)

这道题将前缀和数组扩展到了二维:

在构建前缀和数组时,可以定义前缀和数组(i, j)的值为原矩阵到由(0, 0)到(i - 1, j - 1)构成的子矩阵内部的元素之和,任意矩阵都可以由几个子矩阵的加减运算得到,原理如下图:

 代码如下:

class NumMatrix {
    int[][] sumArr;

    public NumMatrix(int[][] matrix) {
        int m = matrix.length, n = matrix[0].length;
        sumArr = new int[m + 1][n + 1];
        //初始化前缀和数组
        for(int i = 1; i < m + 1; i++){
            for(int j = 1; j < n + 1; j++){
                sumArr[i][j] = sumArr[i][j - 1] + sumArr[i - 1][j] + matrix[i - 1][j - 1] - sumArr[i - 1][j - 1];
            }
        }
    }
    
    public int sumRegion(int row1, int col1, int row2, int col2) {
        // System.out.println("------");
        // for(int[] row : sumArr){
        //     System.out.println(Arrays.toString(row));
        // }
        return sumArr[row2 + 1][col2 + 1] - (sumArr[row2 + 1][col1] + sumArr[row1][col2 + 1] - sumArr[row1][col1]);
    }
}

/**
 * Your NumMatrix object will be instantiated and called as such:
 * NumMatrix obj = new NumMatrix(matrix);
 * int param_1 = obj.sumRegion(row1,col1,row2,col2);
 */

 

 

 

class NumArray { //前缀和数组 int[] sumArr;
public NumArray(int[] nums) { sumArr = new int[nums.length + 1]; for(int i = 1; i < sumArr.length; i++){ sumArr[i] = sumArr[i - 1] + nums[i - 1]; } }   public int sumRange(int left, int right) { //计算[i, j]范围内的和是用sumArr[j + 1] - sumArr[i]计算 return sumArr[right + 1] - sumArr[left]; } }
/** * Your NumArray object will be instantiated and called as such: * NumArray obj = new NumArray(nums); * int param_1 = obj.sumRange(left,right); */

标签:sumArr,前缀,nums,int,NumArray,差分,数组,leetcode
From: https://www.cnblogs.com/xkge/p/17505271.html

相关文章

  • console.log 弊端-数组有值但是打印出来空值
    情况:数组有对象但是length为0原因:该数组原本有值,但是被数组操作api改变了数组,打印出来的值是已经被操作的数组 ......
  • 获取数组对象中的某一属性值
    如果想要获取到arr数组对象中key为name的属性,需要用到引号letarr=[{name:'1',prop:'123'},{name:'2',prop:'111'}]arr.forEach(item=>{console.log('123',item['name'])})......
  • JS(数组)
    一数组的概念问:之前学习的数据类型,只能存储一个值。如果我们想存储班级中所有学生的姓名,那么该如何存储呢?答:可以使用数组(Array)。数组可以把一组相关的数据一起存放,并提供方便的访问(获取)方式。问:什么是数组呢?答:数组是指一组数据的集合,其中的每个数据被称作元素,在数组中可以存......
  • [数据结构]Binary Indexed Trees(树状数组)
    BinaryIndexedTrees(树状数组)1.lowbitlowbit(x)是x的二进制表达式中最低位的1所对应的值。比如,6的二进制是110,所以lowbit(6)=2。lowbit(x)=x&(-x)2.定义,查询,修改(eg1)\(a1,a2,...,an\)能在BZ的时间复杂度下完成:单点加,\(ai+=d\)查询前缀和\(\sum_{i=1}^{x}ai......
  • 189. 旋转数组
    给定一个整数数组nums,将数组中的元素向右轮转k个位置,其中k是非负数。示例1:输入:nums=[1,2,3,4,5,6,7],k=3输出:[5,6,7,1,2,3,4]解释:向右轮转1步:[7,1,2,3,4,5,6]向右轮转2步:[6,7,1,2,3,4,5]向右轮转3步:[5,6,7,1,2,3,4]本题思路一致https://......
  • php 二维数组排序
    主要通过 array_multisort函数来进行排序<?php//原数组$arr=[["name"=>"小明","age"=>18],["name"=>"小红","age"=>7],["name"=>"小刚","age"=>52],[&......
  • 二叉树-快排-leetcode912
    给你一个整数数组nums,请你将该数组升序排列。示例1:输入:nums=[5,2,3,1]输出:[1,2,3,5]示例2:输入:nums=[5,1,1,2,0,0]输出:[0,0,1,1,2,5]提示:1<=nums.length<=5*104-5*104<=nums[i]<=5*104思路:快排,或者叫前序二叉树,排序后端结果是一个二叉搜索树//lee......
  • 941. 有效的山脉数组
    给定一个整数数组arr,如果它是有效的山脉数组就返回true,否则返回false。让我们回顾一下,如果arr满足下述条件,那么它是一个山脉数组:arr.length>=3在0<i<arr.length-1条件下,存在i使得:arr[0]<arr[1]<...arr[i-1]<arr[i]arr[i]>arr[i+1]>...>arr[ar......
  • mongodb第八篇:数组操作
    db.students.insertOne({"_id":1,"grades":[80,85,90]})db.students.insertOne({"_id":2,"grades":[88,90,92]})db.students.insertOne({"_id":3,"grades":[85,100,90]})需求1、把_id为1的文档的grades数组中的85改成8......
  • leetcode 48 旋转图像 rotate-image【ct】
    ====思路:1.对角线翻折  i=0;i<matrix.lengthj=i;j<matrix.lengthmatrix[i][j]matrix[j][i]=matrix[j][i]matrix[i][j]2.左右翻折i=0i<matrix.lengthj=0j<Math.floor(matrix.length/2)matrix[i][j]matrix[i][matrix.lengt......