一、leetcode 413 等差数列的划分–子数组
题目描述(例子):
A = [1, 2, 3, 4]
返回: 3, A 中有三个子等差数组: [1, 2, 3], [2, 3, 4] 以及自身 [1, 2, 3, 4]。
代码如下:
class Solution {
public:
int numberOfArithmeticSlices(vector<int>& nums) {
int n=nums.size();
vector<int>dp(n,0);
for(int i=2;i<n;i++){
if(nums[i]-nums[i-1]==nums[i-1]-nums[i-2]){
dp[i]=dp[i-1]+1;
}
}
return accumulate(dp.begin(),dp.end(),0);
}
};
二、leetcode 446 等差数列的划分–子序列
题目描述(示例):
输入:[2, 4, 6, 8, 10]
输出:7
解释:
所有的等差子序列为:
[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<int>& A) {
int n=A.size();
if(n<3) return 0;
int res=0;
unordered_map<int,vector<int>>mp;
vector<vector<int>>dp(n,vector<int>(n,0));
for(int i=0;i<n;i++){
mp[A[i]].push_back(i);//记录所有值对应的索引
}
//dp[j][i]表示以j,i为最后两个元素的等差数列的值
for(int i=0;i<n;i++){
for(int j=0;j<i;j++){
//A[k],A[j],A[i]构成等差数列
long num=(long)2*A[j]-A[i];//求A[k]并过滤
if(num<INT_MIN||num>INT_MAX) continue;
//进行状态转换
for(int k:mp[num]){
if(k<j) dp[j][i]+=dp[k][j]+1;//在dp[k][j]的基础上,多了A[k],A[j],A[i]所以加1
}
res+=dp[j][i];
}
}
return res;
}
};