题目链接
https://leetcode.com/problems/valid-permutations-for-di-sequence/
题意
我们给出 S,一个源于 {‘D’, ‘I’} 的长度为 n 的字符串 。(这些字母代表 “减少” 和 “增加”。)
有效排列 是对整数 {0, 1, …, n} 的一个排列 P[0], P[1], …, P[n],使得对所有的 i:
- 如果 S[i] == ‘D’,那么 P[i] > P[i+1],以及;
- 如果 S[i] == ‘I’,那么 P[i] < P[i+1]。
有多少个有效排列?因为答案可能很大,所以请返回你的答案模 10^9 + 7.
题目类型
动态规划
题目分析
又一道动态规划题,涉及到对这种特殊序列的理解。
将求方案的问题拆解一下,求i长度的序列由求i-1长度的序列转换而来。
设f[i][j]为序列{0,1,…,i}以j作为结尾的排列总数。
当前字母为’D’时,显然i-1位上只能够取j+1,j+2,…i-1.但是这样可能会有重复的情况(前面的序列也有j),这种情况我们只需要把序列中大于等于j的数全部加1,则能既满足原有性质又不产生重复(这一点拿几个例子推一下就可以了)。这样j也是可以转移的,因此有$ f[i][j] = f[i-1][j] + f[i-1][j+2] + … + f[i-1][i-1] $
当前字母为’I’时,显然i-1位上只能够取0,1,…j-1.这时仍然会有重复情况,像上文一样解决即可。同时,f[i][0]必定为0,做一下特判即可,可以得到$ f[i][j] = f[i-1][0] + f[i-1][j+2] + … + f[i-1][j-1] $
连续求和很容易用部分和技术搞定,因此复杂度只有$N^{2}$.
关于全部加1举个例子,假如前面的序列是{0,2,3,4,1},此时我们在后面加入3,把大于等于的部分加1,新序列为{0,2,4,5,1,3},数列大小关系不会发生改变。
时间复杂度
$O(N ^ {2})$
源代码
1 | class Solution { |