统计特殊子序列的数目
难度:
标签:
题目描述
代码结果
运行时间: 154 ms, 内存: 20.2 MB
/*
* 思路:
* 使用动态规划来解决这个问题。定义三个变量 count0、count1 和 count2 分别表示以 0、1 和 2 结尾的特殊子序列的数量。
* 遍历数组 nums,根据当前的数字更新这三个变量。
* 1. 如果当前数字是 0,那么 count0 += 1(每个 0 都可以单独成为一个特殊序列的一部分)。
* 2. 如果当前数字是 1,那么 count1 += count0(每个 1 可以和之前的所有 0 组成一个特殊序列)。
* 3. 如果当前数字是 2,那么 count2 += count1(每个 2 可以和之前的所有 1 组成一个特殊序列)。
* 最终答案就是 count2 对 10^9 + 7 取余。
*/
import java.util.stream.*;
public class Solution {
public int countSpecialSubsequences(int[] nums) {
int MOD = 1000000007;
long[] counts = new long[3];
for (int num : nums) {
if (num == 0) {
counts[0] = (counts[0] + 1) % MOD;
} else if (num == 1) {
counts[1] = (counts[1] + counts[0]) % MOD;
} else if (num == 2) {
counts[2] = (counts[2] + counts[1]) % MOD;
}
}
return (int) (counts[2] % MOD);
}
}
解释
方法:
该题解采用动态规划的方法,通过维护三个变量a, b, c来统计以0开始,以1开始和以2结尾的特殊子序列的数量。每次遇到0时,可以选择包含或不包含当前0,因此特殊序列的数量是之前数量的两倍,再加上新开始的一个序列。遇到1时,可以选择包含或不包含当前1,因此以1开始的特殊序列数量是之前数量的两倍,加上所有可能以0结束的序列数量。同理,遇到2时,也是选择包含或不包含当前2,以2结束的序列数量是之前数量的两倍,加上所有可能以1结束的序列数量。最后返回以2结束的特殊子序列的数量。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
在动态规划解法中,初始化a, b, c为0有什么特殊的意义,这是否意味着在序列开始之前不存在任何特殊子序列?
▷🦆
遇到数字0时,为什么要将a的值更新为2*a + 1,这里的+1是代表什么?
▷🦆
当处理数字1和数字2时,为什么要加上之前累积的子序列数量,这样做的目的是什么?
▷🦆
在更新变量b和c的公式中,为什么选择将它们与前一个状态的变量a和b相加?这样的操作有什么特别的意义吗?
▷