LeetCode413. 等差数列划分
如果一个数列 至少有三个元素 ,并且任意两个相邻元素之差相同,则称该数列为等差数列。
- 例如,
[1,3,5,7,9]、[7,7,7,7]和[3,-1,-5,-9]都是等差数列。
给你一个整数数组 nums ,返回数组 nums 中所有为等差数组的 子数组 个数。
子数组 是数组中的一个连续序列。
示例 1:
输入: nums = [1,2,3,4]
输出: 3
解释: nums 中有三个子等差数组:[1, 2, 3]、[2, 3, 4] 和 [1,2,3,4] 自身。
示例 2:
输入: nums = [1]
输出: 0
提示:
1 <= nums.length <= 5000-1000 <= nums[i] <= 1000
思路分析
是等差数列,所以遍历到当前值时,我们只需要判断:
差值相同,是等差数列,按照刚刚的计算公式,将子数列数量增加; 差值不同,更新等差数列的差值,继续往后遍历查找等差数列。 一开始的话,我想用一个数组,分别存储等差序列的开始下标、遍历到当前下标时最终的结果、等差数列的差值,但是转念一想,这些值,同时都只会有一个状态,直接各自用变量保存就好,不需要用数组存储每一个下标时的状态。
所以我们定义了res,用来表示最终的结果;difference,用来表示当前数列的差值;length,用来表示当前数列的长度,用来计算增加的子数列数量。
那之后,我们只要遍历整个数组,通过代码实现我们上面说到的判断逻辑就好。
算法代码
public int numberOfArithmeticSlices(int[] nums) {
if (nums.length < 3) {
return 0;
}
// 先计算出初始差值,也就是数组前两个数之间的差
int res = 0, difference = nums[1] - nums[0], length = 2;
// 从第三个数开始判断,看能不能构成等差数列
for (int i = 2; i < nums.length; i++) {
// 计算差值
int nowDifference = nums[i] - nums[i - 1];
if (nowDifference == difference) {
length++;
// 按照公式直接累加最终的结果
res += length == 3 ? 1 : length - 2;
} else {
// 发现不同,将状态恢复到初始状态,等待下一个等差数列
difference = nowDifference;
length = 2;
}
}
return res;
}
结果详情
算法复杂度
- 空间复杂度:
- 时间复杂度:
在掘金(JUEJIN)一起进步,一起成长!