今日题目
今日LeetCode随机一题:1955.统计特殊子序列的数目【难度:困难】
特殊序列 是由 正整数 个 0 ,紧接着 正整数 个 1 ,最后 正整数 个 2 组成的序列。
- 比方说,[0,1,2] 和 [0,0,1,1,1,2] 是特殊序列。
- 相反,[2,1,0] ,[1] 和 [0,1,2,0] 就不是特殊序列。
一个数组的 子序列 是从原数组中删除零个或者若干个元素后,剩下元素不改变顺序得到的序列。如果两个子序列的 下标集合 不同,那么这两个子序列是 不同的 。
给你一个数组 nums (仅 包含整数 0,1 和 2),请你返回 不同特殊子序列的数目 。由于答案可能很大,请你将它对 10^9 + 7 取余 后返回。
题目解读
输入数据:
nums:List[int]
已知条件:
nums数组中的元素仅限0、1、2三种
题目要求:
计算nums数组中不同特殊子序列的数目,对(10^9+7)取余后返回
举例说明
nums=[0,1,2,2]
则其不同特殊子序列包括[0,1,2, 2 ]、[0,1, 2 ,2]、[0,1,2,2]
算法思想
采用动态规划的思想
zero代表 全0的序列
one代表由 正整数个0和正整数个1组成的序列
two代表由 正整数个0、正整数个1和正整数个2组成的序列
f[0] 代表zero序列数目
f[1] 代表one序列数目
f[2] 代表two序列数目
考虑各个数字的正确组成情况
- 0能和所有的zero组成新的zero,也可以自己单独成为一个新的zero。所以f[0] += f[0] + 1;
- 1能和所有的zero组成新的one,也可以和所有的one组成新的one。所以f[1] += f[0] + f[1]
- 2能和所有的one组成新的two,也可以和所有的two组成新的two。所以f[2] += f[1] + f[2]
f[2]即为所求
代码实现
class Solution:
def countSpecialSubsequences(self, nums: List[int]) -> int:
f, mod = [0, 0, 0], 10**9+7
for num in nums:
f[num] = (f[num]*2 + (f[num-1] if num else 1)) % mod
return f[2]
如果要在我们自己的编辑器里实现,则要完善一下引包以及main函数的实现
from typing import List
class Solution:
def countSpecialSubsequences(self, nums: List[int]) -> int:
f, mod = [0, 0, 0], 10**9+7
for num in nums:
f[num] = (f[num]*2 + (f[num-1] if num else 1)) % mod
return f[2]
def main():
nums = [0, 1, 2, 2]
print(Solution().countSpecialSubsequences(nums))
if __name__=='__main__':
main()