【数据结构】计算给定数组 n - m 范围的和

问题:查询给定数组 [1, 2, 3, 4] 的 n~m 范围内的和?

直接算的话我们可以遍历 n ~ m 求和,如果查询次数很频繁的话,就会消耗大量的时间,因此我们可以设计一个数据结构进行预处理。

方法一

采用 4 * 4 矩阵存储,直接将 n 到 m 的值全部计算出置入二维数组,需要用到直接取。

0123
013610
1259
237
34

此法会存在 n * n / 2 大小的空间浪费,并且建立该表示时间消耗大。

方法二

采用前缀和方式存储,采用一维数组的方式存储,实际上就是上述矩阵的第一行,该一维数组中存储的是从 0 到 n 的累加值,当咱们需要取从 n 到 m 的累加值时,直接使用 arr[n] - arr[m - 1] 即可。

前缀和数组

0123
13610

代码:

public class PreSum {

    static int[] preSum;

    public PreSum(int[] arr) {
        preSum = new int[arr.length];
        preSum[0] = arr[0];

        for (int i = 1; i < arr.length; i++) {
            preSum[i] = preSum[i - 1] + arr[i];
        }
    }

    public static int rangeSum(int n, int m) {
        return m == 0 ? preSum[n] : preSum[n] - preSum[m - 1]; 
    }
}

优劣

第二种方式非常简洁,但是在查询次数远超出数据空间时,此时矩阵存储会更好,直接取出值,而不需要计算一下再将值取出。

比如,在 1000 长度的数组中计算 n 到 m 的累加,进行上亿次查询,这时整个数据空间才 100 万,直接取值显然比计算后再取值快很多,空间消耗也可以接受。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值