- Leetcode 3351. Sum of Good Subsequences
- 1. 解题思路
- 2. 代码实现
- 题目链接:3351. Sum of Good Subsequences
1. 解题思路
这一题算是一个比较典型的动态规划的题目。
我们首先定义两个动态规划的数组 c i c_i ci和 s i s_i si,分别表示:
- c i c_i ci: 以第 i i i个位置作为起点的满足条件的子序列的个数
- s i s_i si:以第 i i i个位置作为起点的满足条件的子序列元素之和的总和
则显然我们可以给出递推关系:
c i = 1 + ∑ j = i + 1 N δ ( n i − 1 − n j ) ⋅ c j + ∑ j = i + 1 N δ ( n i + 1 − n j ) ⋅ c j s i = c i ⋅ n i + ∑ j = i + 1 N δ ( n i − 1 − n j ) ⋅ s j + ∑ j = i + 1 N δ ( n i + 1 − n j ) ⋅ s j \begin{aligned} c_{i} &= 1 + \sum\limits_{j=i+1}^{N}\delta(n_i-1 - n_j)\cdot c_j + \sum\limits_{j=i+1}^{N}\delta(n_i+1 - n_j)\cdot c_j \\ s_{i} &= c_i \cdot n_i + \sum\limits_{j=i+1}^{N}\delta(n_i-1 - n_j)\cdot s_j + \sum\limits_{j=i+1}^{N}\delta(n_i+1 - n_j)\cdot s_j \end{aligned} cisi=1+j=i+1∑Nδ(ni−1−nj)⋅cj+j=i+1∑Nδ(ni+1−nj)⋅cj=ci⋅ni+j=i+1∑Nδ(ni−1−nj)⋅sj+j=i+1∑Nδ(ni+1−nj)⋅sj
其中, n i n_i ni表示第 i i i个元素的值, δ ( x ) \delta(x) δ(x)函数的定义为当且仅当 x = 0 x=0 x=0是 δ ( x ) = 1 \delta(x) = 1 δ(x)=1,其他时候均有 δ ( x ) = 0 \delta(x) = 0 δ(x)=0。
此时,我们只需要另外再使用两个hashmap来记录当前所有值下对应的 ∑ j = i + 1 N δ ( x − n j ) ⋅ c j \sum\limits_{j=i+1}^{N}\delta(x-n_j)\cdot c_j j=i+1∑Nδ(x−nj)⋅cj以及 ∑ j = i + 1 N δ ( x − n j ) ⋅ s j \sum\limits_{j=i+1}^{N}\delta(x-n_j)\cdot s_j j=i+1∑Nδ(x−nj)⋅sj这两个值即可。
然后,我们就可以用一个逆序的动态规划快速得到我们最终的答案了。
2. 代码实现
给出python代码实现如下:
MOD = 10**9+7
class Solution:
def sumOfGoodSubsequences(self, nums: List[int]) -> int:
n = len(nums)
cnt = [0 for _ in range(n)]
s = [0 for _ in range(n)]
cumcnt = defaultdict(int)
cumsum = defaultdict(int)
for i in range(n-1, -1, -1):
cnt[i] = (1 + cumcnt[nums[i]-1] + cumcnt[nums[i]+1]) % MOD
s[i] = (nums[i] + (cumcnt[nums[i]-1]+cumcnt[nums[i]+1])*nums[i] + cumsum[nums[i]-1] + cumsum[nums[i]+1]) % MOD
cumcnt[nums[i]] += cnt[i]
cumsum[nums[i]] += s[i]
ans = 0
for x in s:
ans = (ans+x) % MOD
return ans
提交代码评测得到:耗时655ms,占用内存41.6MB。