Description

给定一个长度为n的数组a,求具有公差的子序列的方案数,子序列要求长度大于等于3。

Constraints

  • 1n1000
  • 231ai2311

Solution

想到一个不好做的递推公式:设dp[i][j],表示以i结尾且公差为nums[i]nums[j]的子序列方案数。设想美好但是推不动,似乎没法在dp[i1][?]反推nums[j]……

那改一改:设dp[i][d],表示以i结尾的公差为d的子序列方案数。这下子第二维用哈希表维护就好了。

另外注意一下是求全部序列而不是只求dp[n1],还有必踩坑的溢出情况。

Code

class Solution {
public:
    int numberOfArithmeticSlices(vector<int>& nums) {
        // NOTE
        using L = long long;
        // dp:  len(seq) > 1
        // ans: len(seq) > 2
        unordered_map<L, int> dp[1003];
        int ans = 0;
        for(int i = 0; i < nums.size(); ++i) {
            for(int j = 0; j < i; ++j) {
                auto d = L(nums[i]) - nums[j];
                auto iter = dp[j].find(d);
                auto v = iter != dp[i-1].end() ?
                        iter->second : 0;
                // v: {any seq, nums[i]}
                // 1: {nums[j], nums[i]}
                dp[i][d] += v + 1;
                ans += v;
            }
        }
        return ans;
    }
};

LeetCode-446 Arithmetic Slices II - Subsequence