题目地址:
https://leetcode.com/problems/arithmetic-slices/
给定一个长 n n n数组 A A A,问其有多少个长度大于等于 3 3 3的子数组恰好是等差数列。
任何一个等差数组都可以将左右端点向两边尽可能的扩张从而构成一个更长的等差数组,一个长 k k k的等差数组(按照题目要求 k ≥ 3 k\ge 3 k≥3),其共有 ( 1 + k − 2 ) ( k − 2 ) 2 \frac{(1+k-2)(k-2)}{2} 2(1+k−2)(k−2)个等差子数组(包括它自己)。所以我们只要将 A A A视作是极大等差数组之拼接,计算每个极大等差数组的长度然后按照上面公式累加即可。代码如下:
public class Solution {
public int numberOfArithmeticSlices(int[] A) {
int res = 0;
// 枚举极大等差子数组的左端点
for (int i = 0; i < A.length; i++) {
// 求其右端点
int j = i + 1;
while (j < A.length && A[i + 1] - A[i] == A[j] - A[j - 1]) {
j++;
}
// 求得极大等差子数组的长度,如果长度大于等于3就累加
int len = j - i;
if (len >= 3) {
res += (1 + len - 2) * (len - 2) / 2;
i = j - 1;
}
}
return res;
}
}
时间复杂度 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)。