Problem
A sequence of number is called arithmetic if it consists of at least three elements and if the difference between any two consecutive elements is the same.
For example, these are arithmetic sequence:
1, 3, 5, 7, 9
7, 7, 7, 7
3, -1, -5, -9
The following sequence is not arithmetic.
1, 1, 2, 5, 7
A zero-indexed array A consisting of N numbers is given. A slice of that array is any pair of integers(P, Q)
such that 0 <= P < Q < N
.
A slice(P, Q)
of array A is called arithmetic if the sequence:
A[P], A[P + 1], ..., A[Q - 1], A[Q]
is arithmetic. In particular, this means that P + 1 < Q
.
The function should return the number of arithmetic slices in the array A.
Example:
A = [1, 2, 3, 4]
return: 3, for 3 arithmetic slices in A: [1, 2, 3], [2, 3, 4] and [1, 2, 3, 4] itself.
题意
输入一个数组,求出该数组中连续的等差数列的数量。
注意
- 等差数列的最短长度为3,对于长度大于3的等差数列,要计算其子集(子序列)数量。
- 只有当连续的序列构成等差关系时,才满足条件。例如,[1, 2, 3, 4, 5]中,[1,3 5]并不是一个符合要求的解。
分析&思路
依然是一道被放在动态规划分类下的题目,但是并没有想到动规的解法QAQ···
按照自己的思路来:
首先找出整个数组中所有满足条件的“长等差数列”(例如,[2, 1, 2, 3, 4, 4, 4, 4]中,所谓的“长等差数列”有[1, 2, 3, 4],[4, 4, 4, 4],而忽略掉[1, 2, 3]、[2, 3, 4]、[4, 4, 4]这样的可视为某个“长等差数列”的子集的等差数列)对于每个满足条件的等差数列,都只记录它的最大长度。
将每个“长等差数列”的长度记录在一个
vector
里sliceLen 对于长度为i的等差数列,其子集数量为
i - 3 + 1
(自行找规律即可,证明略)最后的结果就是遍历
sliceLen
,求子集数量的和即可。
Code
//Runtime: 6ms
//时间复杂度:O(n),空间复杂度:O(n)
class Solution {
private:
//计算长度为sliceLen的等差数列的子等差数列的数量
int _numOfSubslice(int sliceLen){
int result = 0;
for (int i = 1; i <= sliceLen - 3 + 1; i++){
result += i;
}
return result;
}
public:
int numberOfArithmeticSlices(vector& A) {
if (A.empty() || A.size() < 3) return 0;
//计算每个A[i+1]-A[i]
vector diff;
diff.resize(A.size() - 1);
for (int i = 0; i < A.size() - 1; i++)
diff[i] = A[i+1] - A[i];
//sliceLen存储所有“长等差数列”的长度
vector sliceLen;
for (int i = 0; i < diff.size(); i++){
//初始长度为2
int local_sliceLen = 2;
//如果连续的两个diff相等,则意味着开始构成了等差数列
while((i < diff.size() - 1) && (diff[i] == diff[i+1])){
i++;
local_sliceLen++;
}
if (local_sliceLen >= 3) sliceLen.push_back(local_sliceLen);
}
int result = 0;
for (int i = 0; i < sliceLen.size(); i++)
result += _numOfSubslice(sliceLen[i]);
return result;
}
};