【模板】前缀和

31 阅读2分钟

一、题目

描述

给定一个长度为n的数组 a1​,a2​,....an​.

接下来有q次查询, 每次查询有两个参数 l, r.

对于每个询问, 请输出 a(l)​+a(l+1)​+....+a(r)​

输入描述:

第一行包含两个整数 n 和 q .

第二行包含 n 个整数, 表示 a1​,a2​,....an​.

接下来 q 行,每行包含两个整数 l和r.

输出描述:

输出q行,每行代表一次查询的结果.

示例1

输入:

3 2
1 2 4
1 2
2 3

输出:

3
6

二、前缀和解析

上一篇博客我讲了一道前缀和的例题(除自身以外数组的乘积),是本文的扩展补充。通过这道例题希望能让大家了解前缀和这种算法的底层逻辑。

什么是前缀和?

前缀和,顾名思义,就是某一个数组的前n项的总和。设我们有一个数组 arr,其前缀和数组记为 Sum,那么 Sum[i] 就表示从 arr[0] 加到 arr[i] 的总和。

例如,假设有一个数组 arr = [3, 5, 2, -1, 4],对应的前缀和数组就是 Sum = [3, 8, 10, 9, 13]。其中,Sum[0] = arr[0]Sum[1] = arr[0] + arr[1],以此类推。

前缀和能做什么?

前缀和最大的优势在于使区间和的查询变得异常迅速。

假如我们想知道数组 arr 中从第 i 个元素到第 j 个元素的总和,普通的做法可能需要遍历 ij 的所有元素并累加,但如果使用了前缀和,我们只需要一步操作:Sum[j] - Sum[i - 1](当 i > 0 时)。如果 i 是 0,那么区间和直接就是 Sum[j]

这种方法对于频繁查询数组中某个范围内元素的总和特别有效。在数据分析、图像处理、动态规划等领域都有广泛的应用。

思路解析

这道题的题目很绕,我看了得好几遍菜捋明白。

它的目的就是我们返回数组中某几个数的相加之和,所以,我们就可以利用前缀和来优化。

通过前缀和思想,我们需要创建一个数组 dp ,用于记录 arr 中每一位和它前面所有元素的和

前缀和的计算方式,则是这条公式:dp[ i ] = dp[ i-1 ] + arr[ i ].

最后返回题目所要求的元素之和即可。

三、完整代码

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int q = in.nextInt();
        int[] arr = new int[n+1];
        for (int i = 1; i <= n ; i ++){
            arr[i] = in.nextInt();
        }

        long[] dp = new long[n+1];
        for(int i = 1; i<= n ; i ++){
            dp[i] = dp[i-1] + arr[i];
        }

        while(q > 0){
            int l = in.nextInt();
            int r = in.nextInt();
            System.out.println(dp[r] - dp[l-1]);
            q--;
        }

    }
}

以上就是本篇博客的全部内容啦,如有不足之处,还请各位指出,期待能和各位一起进步!