算法26.0
【模板】前缀和_牛客题霸_牛客网
前缀和模板_一维前缀和
自己的理解:
时间复杂度怎么实现O(1) ?
设定一个前缀和数组 需要的时候直接从前缀和数组里面得到结果 时间复杂度就是O(1)
为什么要搞这个前缀和数组?
因为时间复杂度小
前缀和数组为什么下标要从1开始呢?
为了处理边界情况 因为从0开始的时候 有边界情况 状态转移方程dp[i]=dp[i-1]+arr[i]
如果是零开头的话 数组就会产生小标异常(-1)
前缀和的思想是什么?
是预处理 通过预先计算和存储数组累积和 使得在后续的查询中能以O(1)时间复杂度快速计算任意区间的和
为什么前缀和数组的大小为n+1呢?
主要是为了简化边界条件处理 如果前缀和的数组大小是n的话 后续计算 arr[i] 到 arr[j] 的和的公式dp[ j ] - dp[i-1] 的时候就会出现数组越界异常
如果是前缀和数组大小是n+1的话,return prefix[j+1] - prefix[i];

如何实现前缀和数组? (一维) ?
前缀和:快速得到数组某一连续区间的和 时间复杂度为O(1)
创建一个数组和题目数组长度一样 作为前缀和数组的底层
然后讲各个和加入到dp数组里面 注意计算的时候 不用每次都遍历一遍 之前的和+当下的元素就是我们要的结果 for(int i = 1; i <= n ; i++) dp[ i ] = dp[ i-1 ]+ arr[ i ] ;
dp[ i ] 表示[1,i]区间所有元素的和 //状态表示
dp[ i ] = dp[ i-1 ]+ arr[ i ] //状态转移方程


细节:
审题的时候 出现某些条件 可以停下来想一想为什么条件是这样 有的时候可能会给题目提供一些线索 这道题比如数组的下标为什么不是0开始而是1?
审题的时候 条件要清晰一点 这个部分花点时间也是很必要的 例如第一道题目的l和r 要理解清楚分别是什么意思
new int[n+1]因为数组是从1 开始的
别人的讲解:
暴力解法 :直接算就完了 时间复杂度(按照最差的情况):每次都遍历全部元素(n个) 然后q次
所以时间复杂度就是n*q 都去最大的情况 就是10的10次方 这样肯定超时
优化暴力解法:
下面是题目、效果图和代码 :


import java.util.Scanner;public class Main
{public static void main(String[] args) {Scanner in = new Scanner(System.in);//1.输入数据int n = in.nextInt(),q=in.nextInt();int[] arr = new int[n+1];for(int i = 1;i<=n;i++) arr[i] = in.nextInt();//2.预处理一个前缀和数组long[] dp = new long[n+1] ;//可能会出现数组越界异常for(int i = 1;i <= n;i++) dp[i] = dp[i-1] + arr[i] ;//3.使用前缀和数组while(q>0) {int l = in.nextInt(),r=in.nextInt();System.out.println(dp[r]-dp[l-1]) ;q--;}}
}
//xiyu25110&1#4*1
