T1、数组不可变
给定一个整数数组 nums,处理以下类型的多个查询:计算索引 left 和 right (包含 left 和 right)之间的 nums 元素的 和 ,其中 left <= right实现 NumArray 类:NumArray(int[] nums) 使用数组 nums 初始化对象int sumRange(int i, int j) 返回数组 nums 中索引 left 和 right 之间的元素的 总和 ,包含 left 和 right 两点(也就是 nums[left] + nums[left + 1] + ... + nums[right] )
class NumArray {
//创建前缀和数组
private int[] sums;
//输入数组nums
public NumArray(int[] nums) {
sums = new int[nums.length+1];
//填充数组
for(int i = 1; i < sums.length; i++){
sums[i] = sums[i-1] + nums[i-1];
}
}
//返回[left,right]区间内的累加和
public int sumRange(int left, int right) {
return sums[right+1] - sums[left];
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/52e770fb15f963539c2201723255e776.png)
T2、所有奇数长度子数组的和
给你一个正整数数组 arr ,请你计算所有可能的奇数长度子数组的和。子数组 定义为原数组中的一个连续子序列。请你返回 arr 中 所有奇数长度子数组的和 。
![](https://i-blog.csdnimg.cn/blog_migrate/b08540dba4bfa036548c43fe850c36f0.png)
创建长度为n + 1的前缀和数组sums,其中sums[0]=0, 当1≤i≤n时,sums[i] 表示数组arr从下标0到下标i- 1的元素和。得到前缀和数组sums之后,对于0≤start≤end<n,数组arr的下标范围[start, end]的子数组的和为sums[end + 1] - sums[start]
class Solution {
public int sumOddLengthSubarrays(int[] arr) {
int n = arr.length;
int sums[] = new int[n + 1];
//初始化前缀和
for (int i = 1; i <= n; i ++ ) {
sums[i] = sums[i - 1] + arr[i - 1];
}
int result = 0;
for (int len = 1; len <= n; len += 2 ) {
//枚举左端点,限制右端点不越界
for (int start = 0; start + len - 1 < n; start ++ ) {
int end = start + len - 1;
//[start,end]区间和
result += sums[end + 1] - sums[start];
}
}
return result;
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/4b0c8c261777c4bb0a8a3142dfb0b7ae.png)