这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战
leetcode-413-等差数列划分
[博客链接]
[题目描述]
如果一个数列,至少有三个元素 ,并且任意两个相邻元素之差相同,则称该数列为等差数列。
例如,[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 **
Related Topics
- 数组
- 动态规划
- 👍 300 👎 0
[题目链接]
[github地址]
[思路介绍]
思路一:双指针+数学+暴力扫描
- 本题主要分为两步
- 第一步:
- 寻找等差数列
- 等差数列可以通过双指针扫描整个数组,获得所有为等差序列的子数组
- 其中一个指针为起始元素i,然后定义第二个指针j = i + 1
- 元素差为val = nums[j] - nums[i]
- 移动j,求得nums[j]- nums[j-1]==val
- 如果相等:继续移动j,j-i>=2 则为等差数列,长度为j-i+1
- 其余情况:i移动到j的未知进行下一次等差数列判定
- 第二步:
- 根据等差子数组求的其包含的所有等差数组的数量
- 我们假设有一个长度为5的等差子数列[a1,a2,a3,a4,a5]
- 其中包含:
- [a1,a2,a3]
- [a2,a3,a4]
- [a3,a4,a5]
- [a1,a2,a3,a4]
- [a2,a3,a4,a5]
- [a1,a2,a3,a4,a5]
- 根据上述示例可以发现,包含的子数组的数量和其子数组长度有关
- 当数组长度为5时,长度为3的子数列又3个len-n+1
- 数量也就是从1+2+...+n-2
- res = (n-2)*(n-1)/2
public int numberOfArithmeticSlices(int[] nums) {
int idx = 0, n = nums.length, res = 0;
while (idx < n) {
if (idx == n - 1) {
break;
}
int val = idx;
int dis = nums[val + 1] - nums[val];
while (val < n - 1 && nums[val + 1] - nums[val] == dis) {
val++;
}
if (val - idx >= 2) {
res = res + (val - idx - 1) * (val - idx) / 2;
}
idx = val;
}
return res;
}
时间复杂度O(n) 空间复杂度O(1)