题目:
A sequence of numbers 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 sequences:
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 subsequence slice of that array is any sequence of integers (P0, P1, ..., Pk) such that 0 ≤ P0 < P1 < ... < Pk < N.
A subsequence slice (P0, P1, ..., Pk) of array A is called arithmetic if the sequence A[P0], A[P1], ..., A[Pk-1], A[Pk] is arithmetic. In particular, this means that k ≥ 2.
The function should return the number of arithmetic subsequence slices in the array A.
The input contains N integers. Every integer is in the range of -231 and 231-1 and 0 ≤ N ≤ 1000. The output is guaranteed to be less than 231-1.
Example:
Input: [2, 4, 6, 8, 10] Output: 7 Explanation: All arithmetic subsequence slices are: [2,4,6] [4,6,8] [6,8,10] [2,4,6,8] [4,6,8,10] [2,4,6,8,10] [2,6,10]
代码:
class Solution {
public:
int numberOfArithmeticSlices(vector& A) {
if (A.empty()) return 0;
vector> dp(A.size());
int res = 0;
for (int i = 0; i < A.size(); ++i){//i和j均表示下标
for (int j = 0; j < i; ++j){
if ((long)A[i] - (long)A[j] > INT_MAX || (long)A[i] - (long)A[j] < INT_MIN) continue;
int dif = A[i] - A[j];//计算出差值
dp[i][dif] += 1;//如果没有则值为1,如果有的话则值加1;
if (dp[j].find(dif) != dp[j].end()){//这个差值在j的内部存在,可构成等差数列
dp[i][dif] += dp[j][dif];
res += dp[j][dif];
}
}
}
return res;
}
};
分析:这个题和Arithmetic Slices有些区别,主要体现在,构成等差数列的元素可以不是相邻的,即等差数列之间的差不是固定的。在Arithmetic Slices中,构成等差数列的元
相邻,则他们之间的差只有一种,所以在升级版本中我们要保存构成等差数列的差。
1.首先是dp[i][j]的逻辑:
在本题中,假设对于数组num,dp[i][j]表示的是到数组下标为i差位j的等差数列的个数;很显然,当我们新加入一个元素时,假设下标为i,则我们要计算数组中下标
从0到i-1的所有的dp[k][dif]的值,其中,相邻两元素的差<=dif<=num[i]-num[0];如果我们在计算时求得num[i]-num[k]=dif;而刚好在dp[k]中存在差为dif的数(存在就是表明
数组下标为k的元素和前面的元素已经构成差位dif的等差数列),则在等差数列长度增加1时,可以求出截止到数组下标i且构成差为dif的数列的个数。