leetcode1955_go_统计特殊子序列的数目

题目

特殊序列 是由 正整数 个 0 ,紧接着 正整数 个 1 ,最后 正整数 个 2 组成的序列。

比方说,[0,1,2] 和 [0,0,1,1,1,2] 是特殊序列。

相反,[2,1,0] ,[1] 和 [0,1,2,0] 就不是特殊序列。

给你一个数组 nums (仅 包含整数 0,1 和 2),请你返回 不同特殊子序列的数目 。

由于答案可能很大,请你将它对 109 + 7 取余 后返回。

一个数组的 子序列 是从原数组中删除零个或者若干个元素后,剩下元素不改变顺序得到的序列。

如果两个子序列的 下标集合 不同,那么这两个子序列是 不同的 。

示例 1:输入:nums = [0,1,2,2] 输出:3

解释:特殊子序列为 [0,1,2,2],[0,1,2,2] 和 [0,1,2,2] 。

示例 2:输入:nums = [2,2,0,0] 输出:0

解释:数组 [2,2,0,0] 中没有特殊子序列。

示例 3:输入:nums = [0,1,2,0,1,2] 输出:7

解释:特殊子序列包括:

- [0,1,2,0,1,2]

- [0,1,2,0,1,2]

- [0,1,2,0,1,2]

- [0,1,2,0,1,2]

- [0,1,2,0,1,2]

- [0,1,2,0,1,2]

- [0,1,2,0,1,2]

提示:1 <= nums.length <= 105

0 <= nums[i] <= 2

解题思路分析

1、动态规划;时间复杂度O(n),空间复杂度O(1)

leetcode1955_go_统计特殊子序列的数目

var mod = 1000000007

func countSpecialSubsequences(nums []int) int {
   n := len(nums)
   a, b, c := 0, 0, 0
   for i := 0; i < n; i++ {
      if nums[i] == 0 {
         a = (a*2 + 1) % mod // 之前0组合+之前0组合加上当前0+单独0
      } else if nums[i] == 1 {
         b = (b*2 + a) % mod // 之前01组合+之前01组合加上当前1+之前0组合加上当前1
      } else if nums[i] == 2 {
         c = (c*2 + b) % mod // 之前012组合+之前012组合加上当前值2+之前01组合加上当前2
      }
   }
   return c
}

2、动态规划;时间复杂度O(n),空间复杂度O(1)

var mod = 1000000007

func countSpecialSubsequences(nums []int) int {
   n := len(nums)
   dp := make([]int, 3)
   for i := 0; i < n; i++ {
      if nums[i] == 0 {
         dp[0] = (dp[0]*2 + 1) % mod
      } else if nums[i] == 1 {
         dp[1] = (dp[1]*2 + dp[0]) % mod
      } else if nums[i] == 2 {
         dp[2] = (dp[2]*2 + dp[1]) % mod
      }
   }
   return dp[2]
}

总结

Hard题目,动态规划题目,需要理解状态转移方程

展开阅读全文

页面更新:2024-05-22

标签:序列   数目   下标   组合   复杂度   整数   数组   示例   方程   个子   题目   元素   时间   动态   科技   空间

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top