446. Arithmetic Slices II - Subsequence

题目大意:给定数组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;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值