https://leetcode-cn.com/problems/arithmetic-slices-ii-subsequence/
👉 446. 等差数列划分 的升级版, 这也太难了吧。
动态规划 + 哈希表
子序列问题, 不要求连续, 就要想到用动态规划来解题。
动态规划的状态定义:
1. dp[i][diff] 代表以元素 nums[i] 结尾, 差为 diff 的个数。
2. 二维动态规划, 遍历 nums 中的元素对 (nums[i], nums[j])。
3. 动态转移方程: dp[i][diff] += dp[j][diff] + 1。
这里为什么是 += 呢, 因为 dp[j][diff] 是以 diff 为公差的 以 nums[j] 结尾的子序列的个数。
而现在要在这一堆子序列后面加上一个 nums[i]。
比如 nums = [2, 4, 6, 8, 10]
以数字 8 位结尾的公差为 2 的子序列一共有 2 个, 分别是 [4, 6, 8], [2, 4, 6, 8]。
现在数字 10 要加到以 8 结尾公差为 2 的子序列后面, 就有了 [4, 6, 8, 10] 和 [2, 4, 6, 8, 10] 和新的 [6, 8, 10]。
所以要 += 。
4. 题目要求至少有三个元素, i, j 和 diff 正好就是三个元素。
参考力扣官方解答, 二维动态规划我还能做几道简单的, 难的真的就gg了。
class Solution:
def numberOfArithmeticSlices(self, nums: [int]) -> int:
'''
dp = {index: {diff: count}}
'''
dp = [collections.defaultdict(int) for _ in nums]
ans = 0
for i in range(len(nums)):
for j in range(i):
diff = nums[i] - nums[j]
dp[i][diff] += dp[j][diff] + 1
if dp[j][diff]:
ans += dp[j][diff]
return ans- 时间复杂度: O(n^2)
- 空间复杂度: O(n^2)
