Java_前缀和

67 阅读2分钟

题目链接:www.nowcoder.com/practice/ac…

题目描述:

给定一个长度为n的数组a1a_1,a2a_2,……ana_n.

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

对于每个询问, 请输出ala_l+aal+1+....+ara_r

输入描述:

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

第二行包含n个整数, 表示a1a_1,a2a_2,……ana_n.

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

1n1≤n,qq10510^5

109−10^9a[i]a[i]10910^9

1lrn1≤l≤r≤n

输出描述:

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

示例1

输入:

 3 2
 1 2 4
 1 2
 2 3

输出:

 3
 6

解析

题目的意思就是第一行输入一个n,然后再输入一个q,n就代表n个数,这个q就是待会要求和的个数

第二行就是输入n个数,将它存到数组中去

下面的q行,假设输入的第一个数为a,第二个为b,那么就将数组中a-b这个范围的所有数加起来,之后打印

这题的暴力解法就是遍历数组从arr[a] 一直加到arr[b].但是毫不意外会超时

前缀和法如其名,假设数组中有n个数,下标为0的数的前缀和就是arr[0];

下标为1的前缀和就是arr[0] + arr[1];

下标为2的前缀和就是arr[0] + arr[1] + arr[2];

……

假设我们要求下标1到下标2的和的话,我们可以直接用下标2的前缀和减去下标为0的前缀和,所得结果就是arr[1] + arr[2];

在写代码的时候其实还有很多细节,仔细看题,题目中的数组下标是从1开始的。且 l的范围是 1≤l≤r≤n。所以我们在创建数组的时候

如果你想从0开始的话,l就要减一。我们索性从1开始得了,那么我们就要创建n + 1;

代码

 public class Main {
     public static void main(String[] args) {
         Scanner in = new Scanner(System.in);
         
         int n = in.nextInt();
         int q = in.nextInt();
         //创建长度为n + 1的数组,arr[0]不赋值,默认为0
         int[] arr = new int[n + 1];
         //因为使用int可能越界,直接使用long,sum数组就是用来存前缀和的
         long[] sum = new long[n + 1];
         for (int i = 1; i <= n; i++) {
             arr[i] = in.nextInt();
             //将前缀和同时求出,i = 1是,i - 1等于0,sum[0]不赋值默认为0,所以不影响结果
             sum[i] = sum[i - 1] + arr[i];
         }
         //需要求q次,每次求完q--
         while (q != 0) {
             //拿到a、b
             int a = in.nextInt(), b = in.nextInt();
             //注意此处减的是a - 1下标,不明白的话可以自己列一个数组
             long result  = sum[b] - sum[a - 1];
             System.out.println(result);
             q--;
         }
     }
 }