题目描述:
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.
Subscribe to see which companies asked this question
算法:
明显的,本题应该采用动态规划来解决。问题的关键在于状态转移函数的确定。我们用数组dp1来记录前k位中能够构成多少个arithmetic sequence。当我们迭代到第i位时,为了确定前i位中能够构成多少个arithmetic sequence,我们可以利用之前计算过的dp1[i-1]来计算。这里有两种情况:如果数组中,A[i-1],A[i-2],A[i-3]不能构成一个arithmetic sequence,那么dp1[i]=dp1[i-1];如果A[i-1],A[i-2],A[i-3]能够构成一个arithmetic sequence,那么为了计算出数组的前i位中有多少个arithmetic sequence,我们不仅需要知道前i-1位总共有多少个arithmetic sequence,还需要知道,到A[i-1]的最长连续序列的长度是多少。于是我们还需要第二个数组dp2来记录到A[i-1]的最长连续序列的长度len,因为该序列长度可以与A[i]组成len-1个新的arithmetic sequence。例如:假设数组A=[1,3,4,5,6,8,10],并且我们当前迭代到A[4],那么到A[3]的最长连续序列的长度为3。具体代码实现如下:
#include <iostream>
#include <vector>
using namespace std;
int dp1[10000];
int dp2[10000];
int numberOfArithmeticSlices(vector<int>& A)
{
for (int i = 0; i < 10000; i++)
{
dp1[i] = 0;
dp2[i] = 1;
}
for (int i = 0; i <= 3; i++)
dp1[i] = 0;
if (A[2] - A[1] == A[1] - A[0])
{
dp1[3] = 1;
dp2[3] = 2;
}
for (int i = 4; i <= A.size(); i++)
{
if (A[i - 1] - A[i - 2] != A[i - 2] - A[i - 3])
{
dp1[i] = dp1[i - 1];
}
else
{
dp1[i] = dp1[i - 1] + dp2[i - 1];
dp2[i] = dp2[i - 1] + 1;
}
}
return dp1[A.size()];
}