leetcode 446.等差数列划分2-子序列(关键点详解)

这道题是此题的升级版,之前那题仅仅考虑的是连续的子序列,本题允许非连续子序列的存在。

初略一看,也是采用动态规划方法解决。

例如:

1 2 3 4 5

这个等差数列,在链接中题的结果为6,而在本题的结果为7,包含了非连续等差子序列1 3 5

7 7 7 7 7

此例子中,在链接中题结果为6,在本题的结果中为16,其中例子为:7 7 7 原数列中的第一个7,第二个7,以及第五个7。

因此两道题没有必然上的联系,由此看来要先定义状态,如果仅按照之前的定义为dp[i],则到i+1时不会确定每个公差不同的非连续子序列数的个数,因此需要定义为dp[i][d],表示遍历到nums[i]数时,公差为d的子序列的个数。

 

转移方程

 在进行转移方程确定前,要先提到一个概念。

弱等差子数列:即至少两个元素构成的子数列。

我们首先考虑的都为弱等差子数列,不考虑数列强制长度至少为3的情况。

在[0,...,i-1]任选一个数j,令公差d=nums[i]-nums[j],此时一定要注意dp[i][d]的含义,含义更明显就是以nums[i]结尾的,公差为d的等差子序列数目。因此在i和j之间的关系如下:

                                                        dp[i][d]=dp[j][d]+1;

 dp[i][d]就是在以nums[j]结尾,公差也为的d的子序列后面加上一个数nums[i],因此,按照状态定义,dp[i][d]为dp[j][d]的所有子序列末尾加上nums[i]都在内,格外再包含子序列{nums[j],nums[i]}。

最后将[0,...,i-1]中的每个i一直相加,状态转移方程为:

                                                dp[i][d]=\sum (dp[j][d]+1)

初始条件

dp数组开始全为0。

最后结果 

以任意数结尾,公差d大于等于1的值的总和result。

代码数据结构:

 由于公差d的范围很广,采用map这种hash表示加快相应dp[j][d]的查找。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值