package class02;
/***
* 题:有一个数组arr,给定两个索引位置L和R,求arr[L, R],即这两个索引之间的所有数的累加和。
*
* 思路:方式一,RangeSum1:
* 设计一个矩形,将来每两个索引之间的数的和,都记录下来。最后返回时,根据参数L, R,锁定矩阵中的那一个数,直接返回结果。
* 方式二:RangeSum2:
* 前缀和方式,根据已知数组arr,创建一个长度相等的新数组newArr,
* 第一个元素为arr[0],第二个元素为arr[0]+arr[1],第三个元素为arr[0]+arr[1]+arr[2]...以此类推。
* 即每一个位置i的元素为,(从原数组的第一个元素,一直加到索引为i的元素的总和)。
* 那么,arr[L, R]的结果是:
* 1.如果L为0,则结果为arr[R];
* 2.否则,结果为arr[R] - arr[L-1]
*/
public class Code01_PreSum {
public static void main(String[] args) {
int[] arr = {5, 4, 6, -3, 2, 3};
// [5, 9, 15, 12, 14, 17]
//这个嵌套for循环输出的结果,就是RangeSum1的矩阵。
RangeSum1 rangeSum0 = new RangeSum1(arr);
for (int i = 0; i <= 5; i++) {
for (int j = 0; j <= 5; j++) {
int sum1 = rangeSum0.rangeSum(i, j);
System.out.print(sum1 + "\t");
}
System.out.println();
}
System.out.println("===========================");
//举例测试
int L = 1;
int R = 4;
RangeSum1 rangeSum1 = new RangeSum1(arr);
int sum1 = rangeSum1.rangeSum(L, R);
System.out.println("sum1 = " + sum1);
RangeSum2 rangeSum2 = new RangeSum2(arr);
int sum2 = rangeSum2.rangeSum(L, R);
System.out.println("sum2 = " + sum2);
}
/*
0 1 2 3 4 5
0 5 9 15 12 14 17
1 X 4 10 7 9 12
2 X X 6 3 5 8
3 X X X -3 -1 2
4 X X X X 2 5
5 X X X X X 3
*/
//1.矩阵解法
public static class RangeSum1 {
private int[] arr;
public RangeSum1(int[] array) {
arr = array;
}
public int rangeSum(int L, int R) {
int sum = 0;
for (int i = L; i <= R; i++) {
sum += arr[i];
// System.out.print(sum + "\t");//可以打印细节
}
// System.out.println();
return sum;
}
}
//2.前缀和解法
public static class RangeSum2 {
private int[] preSum;
public RangeSum2(int[] array) {
int N = array.length;
preSum = new int[N];
preSum[0] = array[0];
for (int i = 1; i < N; i++) {
preSum[i] = preSum[i - 1] + array[i];
}
}
public int rangeSum(int L, int R) {
return L == 0 ? preSum[R] : preSum[R] - preSum[L - 1];
}
}
}
运行结果:
5 9 15 12 14 17
0 4 10 7 9 12
0 0 6 3 5 8
0 0 0 -3 -1 2
0 0 0 0 2 5
0 0 0 0 0 3
===========================
sum1 = 9
sum2 = 9