力扣413-等差数列划分-numberOfArithmeticSlices-Java
题目描述
如果一个数列 至少有三个元素 ,并且任意两个相邻元素之差相同,则称该数列为等差数列。
给你一个整数数组 nums,返回数组 nums 中所有为等差数组的 子数组 个数。子数组是数组中的一个连续序列。
所属题型
动态规划 数组
分析:
首先,比较容易的判断题目属于动态规划类型。在确定属于动态规划题目的基础上,那么我们就应该致力于寻找状态函数,也就是分别计算最小单元。就像典型的动态规划题目爬楼梯一样,每一次结果值都依赖于前面一个或者两个。
这里,题目要求数列至少包含三个元素,因此最小单元就是长度为3的数列,对于长度小于3的数组直接返回0即可。
如何寻找动态函数呢?
首先,我们按照经验设置一个数组,分别保存每个元素加入到队列能够组成的等差数列的个数。
其次,对于前两个元素,我们计算差值获得初始公差d,然后扫描第三个元素,这时候,如果其与第二个元素的差值等于上次计算的差值d,则表示当前三个元素能够组成等差数列,那么个第三个元素对应的组成等差数列的个数为1;
接着,继续扫描第四个元素,这里可以分为两种情况:
- 对于第四个元素与第三个元素差值相同,则表示新加入的第四个元素与前三个元素能够组成等差数列,这时候,第四个元素的加入能够形成的等差数列个数为多少呢?分析一下,第四个元素加入后组成等差数列,那么肯定包含了前面三个元素组成的等差数列个数,同时由于它的加入,又新加入了四个元素的等差数列,相比之下,第四个元素组成的等差数列个数是第三个元素个数+1,所以此时组成的个数为2;如果这时候所有元素扫描完毕,则记录数组的和就是返回值; 这里就可以分析出动态函数为dp[i] = dp [i-1] + 1
- 另外一种情况,如果第四个元素的加入不能组成等差数列,则记录数组直接为0即可,同时计算新的公差并更新。此时操作为 dp[i] = 0; d = nums[i] - nums[i-1]
实现方式-Java
public int numberOfArithmeticSlices(int[] nums) {
if(nums.length<3)
return 0;
int d = nums[1] - nums[0];//计算初始公差
int[] res = new int[nums.length];//记录数组
res[0] = 0;//设置初始值
res[1] = 0;
for (int i = 2; i < nums.length; i++) {//从第三个元素开始扫描
//注意,上下计算公差的方式要一致
if(nums[i] - nums[i-1] == d){
res[i] = res[i-1] + 1;
}else{
res[i] = 0;//上述的情况二,将记录值置为0;
d = nums[i] - nums[i-1];//同时更新公差。
}
}
return Arrays.stream(res).sum();
}