303. 区域和检索 - 数组不可变 & 304. 二维区域和检索 - 矩阵不可变

303. 区域和检索 - 数组不可变

本文主要是记录,方便日后遇到相同题的归纳。(主要思路均来自下面两篇参考文章的提示)

这两题,主要考察的是前缀和,也是包含了动态规划思想。
在这里插入图片描述

题目要求的是:求数组[i, j]范围内的值,且会不断的调用求区域和方法,所以每次调用就计算[i, j]的和,时间复杂度太大

所以,能想到的是,提前维护一个数组,该数组能够计算出[i,j]的区域和,但是由于给出的i、j范围不定,所以不可能提前想好所有可能

所以,有没有间接的计算区域和的方法,使之满足O(1)的时间复杂度

观察发现**[i, j] = [0 , j] - [0, i - 1]**,所以我们可以维护一个数组,该数组计算[0, k]的和,那么求区域和只需要带入该公式即可:

class NumArray {
    int len;        // 求数组的长度
    int[] arr;
    int[] preSum;		// 辅助数组,长度 + 1(0之前的前缀和也需要计算,统一边界条件)
    public NumArray(int[] nums) {				// 初始化
        len = nums.length;
        arr = nums;
        preSum = new int[len + 1];  // 求前缀和的数组
        preSum[0] = 0;
        for(int i = 0; i < len; i++){
            preSum[i + 1] = preSum[i] + arr[i];
        }
    }
    
    public int sumRange(int i, int j) {
        return preSum[j + 1] - preSum[i];
    }
}

——本质就是能够想到前缀和

304. 二维区域和检索 - 矩阵不可变

在这里插入图片描述
和上面的一样,只不过将一维变成二维的。

也还是需要求前缀和,那么此时的前缀和是指从[0,0]~[i, j]范围内的所有数字之和,而前缀和的计算公式变成了:

S[i, j] = S[i, j - 1] + S[i - 1, j] - S[i - 1, j - 1] + [i, j]的值(纸上画图即可)

而[i, j - 1]、[i - 1, j]、[i - 1, j - 1]都是之前计算好的,可以直接使用,注意为了处理边界情况,所以辅助数组helper 行和列各+1。

——那么在初始化的时候,就可以直接计算出前缀和的值。

——其实,这个也是一个递推方程式,所以本质上是动态规划

那边区域和该如何求呢?

S[i1, j1, i2, j2] = S[i2, j2] - S[i2, j2 - 1] - S[i2 - 1, j2] + S[i1 - 1, j1 - 1]

class NumMatrix {
    int[][] matrix;
    int[][] help;
    public NumMatrix(int[][] matrix) {
        if(matrix.length != 0){			// 传入空数组,就不管直接放弃初始化
            this.matrix = matrix;
            help = new int[matrix.length + 1][matrix[0].length + 1];
            for(int i = 1; i <= matrix.length; i++){
                for(int j = 1; j <= matrix[0].length; j++){
                    help[i][j] = help[i - 1][j] + help[i][j - 1] - help[i - 1][j - 1] 
                        		 + matrix[i - 1][j - 1];
                }
            }
        }
    }
    
    public int sumRegion(int row1, int col1, int row2, int col2) {
        return help[row2 + 1][col2 + 1] - help[row2 + 1][col1] - help[row1][col2 + 1] + help[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);
 */

参考:

  1. https://leetcode-cn.com/problems/range-sum-query-immutable/solution/presum-qian-zhui-he-xiang-xi-jiang-jie-b-nh23/
  2. https://leetcode-cn.com/problems/range-sum-query-2d-immutable/solution/ru-he-qiu-er-wei-de-qian-zhui-he-yi-ji-y-6c21/
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值