2018/11/18
903. Valid Permutations for DI Sequence
问题描述:
We are given S
, a length n
string of characters from the set {'D', 'I'}
. (These letters stand for “decreasing” and “increasing”.)
A valid permutation is a permutation P[0], P[1], ..., P[n]
of integers {0, 1, ..., n}
, such that for all i
:
- If
S[i] == 'D'
, thenP[i] > P[i+1]
, and; - If
S[i] == 'I'
, thenP[i] < P[i+1]
.
How many valid permutations are there? Since the answer may be large, return your answer modulo 10^9 + 7
.
测试样例:
Example 1:
Input: "DID"
Output: 5
Explanation:
The 5 valid permutations of (0, 1, 2, 3) are:
(1, 0, 3, 2)
(2, 0, 3, 1)
(2, 1, 3, 0)
(3, 0, 2, 1)
(3, 1, 2, 0)
Note:
1 <= S.length <= 200
S
consists only of characters from the set{'D', 'I'}
.
问题分析:
本题难度为Hard!属于动态规划问题,已给出的函数定义为
class Solution:
def numPermsDISequence(self, S):
"""
:type S: str
:rtype: int
"""
本题可采取动态规划算法求解,思路来源于一个大佬给出了例子,这里首先分析这个例子:
对于上述的测试样例"DID"
,求数字{0,1,2,3}
组成的序列的排列方式数量;有如下的分析图:
其中dp[i][j]
表示从{0,1,2,3}
中取i+1
个数字时(即排列序列的前i+1
个数),第i+1
个数为剩余的数字中第j+1
小的数字的排列方法数量。括号内为排列方式。
观察上图中的连线,可以总结规律:
当第i
个数对应的字符为D
时,dp[i+1][j]=dp[i][j+1]+dp[i][j+2]+...+dp[i][n-1-i]
;
当第i
个数对应的字符为I
时,dp[i+1][j]=dp[i][j]+dp[i][j-1]+...+dp[i][0]
;
当i=0
时,dp[i][j]=1
;
分析可以改善代码降低空间复杂度,代码实现如下;
代码实现:
class Solution:
def numPermsDISequence(self, S):
"""
:type S: str
:rtype: int
"""
dp = [1] * (len(S) + 1)
for c in S:
if c == "I":
dp = dp[:-1]
for i in range(1, len(dp)):
dp[i] += dp[i - 1]
else:
dp = dp[1:]
for i in range(len(dp) - 1)[::-1]:
dp[i] += dp[i + 1]
return dp[0] % (10**9 + 7)