一、题目
描述
给定一个长度为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
个元素的总和,普通的做法可能需要遍历 i
到 j
的所有元素并累加,但如果使用了前缀和,我们只需要一步操作: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--;
}
}
}
以上就是本篇博客的全部内容啦,如有不足之处,还请各位指出,期待能和各位一起进步!