「算法」前缀和

这篇具有很好参考价值的文章主要介绍了「算法」前缀和。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前缀和主要解决求数组中某段区间元素和的问题,使用前缀和解决问题的步骤如下:

  1. 预处理一个前缀和数组
  2. 使用这个数组

一维前缀和

现在有一个一维数组nums

  • 预处理前缀和数组
    定义一个数组 dp[]dp[i]表示 nums 中 [0,i-1] 区间的元素和,那我们就有 dp[i] == dp[i-1] + nums[i-1]这个递推关系
    然后就可以来初始化 dp 数组:
for(int i = 1;i <= len;i++) 
	dp[i] = dp[i-1]+nums[i-1];

这里的 dp 数组我们从下标为1处开始放值,这是因为如果 i 为 0,那 i-1 就非法了,所以我们从1开始,这样就不用单独讨论 i 为 0 的情况(注意 dp 的长度应比 nums 多1,而且循环的范围是[1, len]

  • 使用前缀和数组
    接下来使用处理好的前缀和数组,用下面的模板题来演示一下:
    区域和检索——数组不可变

前缀和不难,主要是不同数组间下标的映射关系不好理解,比如题中要我们求 nums 的[left,right]的和,nums 的 left 对应到 dp 中的下标是 left + 1,right 对应 right + 1,所以这个区间的和就是dp[right+1]-dp[left],用文字解释就是 nums 的 0 到 right 的区间和减掉 0 到 left - 1 的 区间和
代码如下:

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

二维前缀和

以一道模板题展开讲解:
二维区域和检索——矩阵不可变

与处理一维数组一样,在处理二维数组的时候,我们行和列都从下标为1处开始
要算[i,j]处的前缀和,我们通过下图的方式来计算
(这里直接贴力扣官方题解的图了,官方的图比较好看,不过官方的题解真的就是一坨…):
「算法」前缀和,算法详解,算法
简单来说就是有个地方算重复了,这块地方就是黄色和蓝色重叠的绿色部分:f[i-1][j-1],需要把它减掉

此外还要注意下标的映射关系,因为前缀和数组多定义了一行一列,所以原数组matrix[i][j]的前缀和,应该放到前缀和数组arr[i+1][j+1]。比如对于arr中(3,3)处的元素,它其实对应的是matrix中的(2,2)
图示如下,其中绿色部分就是为了避免讨论边界情况而多定义的一行和一列,注意辨别两个数组中三角形的下标
「算法」前缀和,算法详解,算法

构造二维前缀和数组的方法如下:

	public NumMatrix(int[][] matrix) {
        int m = matrix.length;
        int n = matrix[0].length;
        arr = new int[m+1][n+1];
        for(int i = 1;i <= m;i++) {
            for(int j = 1;j <= n;j++) {
                arr[i][j] = arr[i][j-1] + arr[i-1][j] - arr[i-1][j-1] + matrix[i-1][j-1];
            }
        }
	}

构造完之后,接下来就要使用它

这道模板题要我们求原数组中(x1,y1)到(x2,y2)之间的区域的元素和,其实也就模仿刚才计算前缀和的方式进行计算:
「算法」前缀和,算法详解,算法

注意 sumRegion 方法的参数,是原数组的下标,我们要根据映射关系转化为前缀和数组的下标,将四个坐标都加1就ok了

代码如下:

    public int sumRegion(int row1, int col1, int row2, int col2) {
        x1++; y1++; x2++; y2++;
        return arr[x2][y2] - arr[x2][y1-1] - arr[x1-1][y2] + arr[x1-1][y1-1];
    }

整道题的代码为:文章来源地址https://www.toymoban.com/news/detail-839363.html

class NumMatrix {
    int[][] arr;

    public NumMatrix(int[][] matrix) {
        int m = matrix.length;
        int n = matrix[0].length;
        arr = new int[m+1][n+1];
        for(int i = 1;i <= m;i++) {
            for(int j = 1;j <= n;j++) {
                arr[i][j] = arr[i][j-1] + arr[i-1][j]+ matrix[i-1][j-1] - arr[i-1][j-1];
            }
        }
    }
    
    public int sumRegion(int x1, int y1, int x2, int y2) {
        x1++; y1++; x2++; y2++;
        return arr[x2][y2] - arr[x2][y1-1] - arr[x1-1][y2] + arr[x1-1][y1-1];
    }
}

到了这里,关于「算法」前缀和的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法(4)——前缀和

    目录 一、前缀和的定义 二、一维前缀和 三、一维前缀和OJ题 3.1、前缀和 3.2、寻找数组中心下标 3.3、除自身以外数组的乘积 3.4、和为K的数组 3.5、和可被K整除的子数组 3.6、连续数组 四、二位前缀和 4.1、二维前缀和 4.2、矩阵区域和 对于一个给定的数列A,他的前缀和数中 

    2024年01月24日
    浏览(23)
  • 前缀和算法【一维、二维】

    首先这种算法适合于求 从 x 到 y 的和 。 一维代码十分简单,我们只需要每个都记录前面所有的和即可,注意细节 下标从1开始 这里我们就看两种情况:一种是 开始时 ,一种是 执行中 在开始时,因为我们是从1开始,a[0] = 0,所以第一个就是temp; 在执行过程中,因为前一个是

    2023年04月18日
    浏览(24)
  • 前缀和算法

    题目链接:前缀和 算法思路 先预处理出来⼀个「前缀和」数组: ⽤ dp[i] 表⽰: [1, i] 区间内所有元素的和,那么 dp[i - 1] ⾥⾯存的就是 [1, i - 1] 区间内所有元素的和,那么:可得递推公式: dp[i] = dp[i - 1] + arr[i] ; 使⽤前缀和数组,「快速」求出「某⼀个区间内」所有元素的

    2024年02月22日
    浏览(26)
  • Java前缀和算法

    通俗来讲,前缀和算法就是使用一个新数组来储存原数组中前n-1个元素的和(如果新数组的当前元素的下标为n,计算当前元素的值为原数组中从0到n-1下标数组元素的和),可能这样讲起来有点抽象,我们举一个例子对其进行说明:给定一个数组nums[],我们创建一个大小为num

    2024年02月06日
    浏览(37)
  • 「算法」前缀和

    前缀和主要解决求数组中某段区间 元素和 的问题 ,使用前缀和解决问题的步骤如下: 预处理一个前缀和数组 使用这个数组 现在有一个一维数组 nums 预处理前缀和数组 定义一个数组 dp[] , dp[i] 表示 nums 中 [0,i-1] 区间的元素和,那我们就有 dp[i] == dp[i-1] + nums[i-1] 这个递推关系

    2024年03月13日
    浏览(25)
  • 算法专题四:前缀和

    一维前缀和 1.输入数组长度n和查询次数q。 2.使用一个一维数组保存数据。 3.使用一个循环获取q次需要查询范围的数据。 4.遍历r-l+1次进行一个范围求和然后输出。 5.时间复杂度:O(n^2) 6.通过不了所有的测试用例。 1.输入数组长度n和查询次数q。 2.使用一个一维数组保存数据。

    2024年02月01日
    浏览(29)
  • 【算法专题】前缀和

    题目链接 - Nowcoder -DP34.前缀和【模板】 Nowcoder -DP34.前缀和【模板】 题目:给定一个长度为n的数组 a1​, a2​, …an. 接下来有q次查询, 每次查询有两个参数l, r. 对于每个询问, 请输出 al + al + 1 + … + ar 输入描述: 第一行包含两个整数n和q. 第二行包含n个整数, 表示 a1, a2, …an. 接

    2024年02月05日
    浏览(26)
  • 【算法优选】前缀和专题——叁

    含义 : 前缀和实际上就是对于长度为n的数组, 我们新建立一个数组长度为n+1,第i个元素的值为前i个元素的和(包括第i个元素) 。 特点 : 前缀和数组比原数组多一个长度。 前缀和的第0个元素的值为0。 根据前缀和数组的特点,求前缀和时。我们只需要用第i个元素的值

    2024年02月06日
    浏览(39)
  • 【算法优选】 前缀和专题——壹

    含义 : 前缀和实际上就是对于长度为n的数组, 我们新建立一个数组长度为n+1,第i个元素的值为前i个元素的和(包括第i个元素) 。 特点 : 前缀和数组比原数组多一个长度。 前缀和的第0个元素的值为0。 根据前缀和数组的特点,求前缀和时。我们只需要用第i个元素的值

    2024年02月08日
    浏览(29)
  • 【算法系列篇】前缀和

    前缀和算法是一种常用的优化技术,用于加速某些涉及连续子数组或子序列求和的问题。它基于一个简单但强大的思想,通过提前计算并存储数组的前缀和,以便在后续查询中可以快速获取任意区间的和。 在许多算法问题中,我们需要频繁地查询子数组的和,例如最大子数组

    2024年02月11日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包