题目大意:给定数组A,找出数组中3个或者3个以上元素能组成的等差数列个数。和这题的简单版不同,数组中某个元素可以被重复使用,以组成不同等差的数列。
分析:显然判断一个元素能不能和之前的元素组成等差数列需要判断这个元素和上一个元素的差值,也就是需要之前的状态,考虑DP
用DP第一件事就是想状态转移方程是啥,然后设置好初始值。
DP[i][dif]表示下标i对应位置的等差为dif的等差数列长度。因为一个元素可能对应多个不同差值,此处使用一个map保存差值<-->所在长度
考虑到数组中出现重复值,相同数字则可以相互替代 : DP[i][dif] += DP[x][dif] > 0? DP[x][dif] + 1 : 1; x属于[0, i)
这样就由已有的信息DP[x][dif] 得到新的信息 DP[i][dif];
class Solution {
public:
int numberOfArithmeticSlices(vector<int>& A) {
if (A.empty()) return 0;
vector< unordered_map<int, int>> dp(A.size());
int res = 0;
for(int i = 0; i < A.size(); i++){
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; // 发现一个dif,将i位置增1 表示当前位置加入数列中。
if(dp[j].find(dif) != dp[j].end()){ // 之前出现了dif,增加之前的长度到当前长度中。
dp[i][dif] += dp[j][dif];
res += dp[j][dif];
}
}
}
return res;
}
};