3699.锯齿形数组的总数 I:前缀和+动态规划
【LetMeFly】3699.锯齿形数组的总数 I:前缀和+动态规划
力扣题目链接:https://leetcode.cn/problems/number-of-zigzag-arrays-i/
给你 三个整数 n、l 和 r。
长度为 n 的锯齿形数组定义如下:
- 每个元素的取值范围为
[l, r]。 - 任意 两个 相邻的元素都不相等。
- 任意 三个 连续的元素不能构成一个 严格递增 或 严格递减 的序列。
返回满足条件的锯齿形数组的总数。
由于答案可能很大,请将结果对 109 + 7 取余数。
序列 被称为 严格递增 需要满足:当且仅当每个元素都严格大于它的前一个元素(如果存在)。
序列 被称为 严格递减 需要满足,当且仅当每个元素都严格小于它的前一个元素(如果存在)。
示例 1:
输入:n = 3, l = 4, r = 5
输出:2
解释:
在取值范围 [4, 5] 内,长度为 n = 3 的锯齿形数组只有 2 种:
[4, 5, 4][5, 4, 5]
示例 2:
输入:n = 3, l = 1, r = 3
输出:10
解释:
在取值范围 [1, 3] 内,长度为 n = 3 的锯齿形数组共有 10 种:
[1, 2, 1],[1, 3, 1],[1, 3, 2][2, 1, 2],[2, 1, 3],[2, 3, 1],[2, 3, 2][3, 1, 2],[3, 1, 3],[3, 2, 3]
所有数组均符合锯齿形条件。
提示:
3 <= n <= 20001 <= l < r <= 2000
解题方法:前缀和+动态规划
相邻不相等 + 递增递减交替 ==> 一个数的可选范围来自上一个数的大小和它的“增减状态”:
- 如果上一个数是递减状态且上一个数是$a$,那么这一个数可以是$[a+1, r]$
- 如果上一个数是递增状态且上一个数是$a$,那么这一个数可以是$[l, a-1]$
倒着来看,这一个数是递增状态的$b$的话,一共有多少种方案可以“到这个数为止是递增的$b$”呢?
这与且仅与上一个数及其增减状态有关。任何递减状态的$[l,b-1]$范围的上一个数都能接上递增状态的这一个数$b$。
令$up[a]$代表上一个数递增到$a$的方案数,$down[a]$代表上一个数递减到$a$的方案数;$up2[b]$代表这一个数递增到$a$的方案数,$down2[b]$代表这一个数递减到$a$的方案数,则有:
- $up2[b]=\sum_{a=l}^{a\lt b}down[a]$
- $down2[b]=\sum_{a=b+1}^{a\leq r}up[a]$
初始值$up[a]=down[a]=1$,上述状态转移方程计算$n-1$次后$\sum_{l}^r(up[i]+down[i])$即为答案。
特别的,计算$up2[b]=\sum_{a=l}^{a\lt b}down[a]$时候的时间复杂度是$b-l$,但我们可以使用前缀和的思想保存计算$up2[b-1]=\sum_{a=l}^{a\lt b-1}down[a]$的结果,则$\sum_{a=l}^{a\lt b}down[a]$可由$up2[b-1]=\sum_{a=l}^{a\lt b-1}down[a]+down[b-1]$在$O(1)$时间内求出。
时空复杂度分析
- 时间复杂度$O(nm)$,其中$m=r-l+1$
- 空间复杂度$O(C)$,其中$C=\max r$,也可以通过下标映射将空间复杂度减小为$O(m)$
AC代码 —— C++
1 | |
同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~
千篇源码题解已开源