903. Valid Permutations for DI Sequence
Description
You are given a string s of length n where s[i] is either:
'D'means decreasing, or'I'means increasing.
A permutation perm of n + 1 integers of all the integers in the range [0, n] is called a valid permutation if for all valid i:
- If
s[i] == 'D', thenperm[i] > perm[i + 1], and - If
s[i] == 'I', thenperm[i] < perm[i + 1].
Return the number of valid permutations perm. Since the answer may be large, return it modulo 109 + 7.
Example 1:
Input: s = "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)
Example 2:
Input: s = "D" Output: 1
Constraints:
n == s.length1 <= n <= 200s[i]is either'I'or'D'.
Solutions
Solution 1: Dynamic Programming
Thinking
A DI string of length \(n\) asks for permutations of \(0..n\). \(n\) can be \(200\), so listing permutations is impossible. After \(i\) numbers are placed, only the rank \(j\) among the remaining values matters for the next rise or fall.
Let \(f[i][j]\) be the number of ways for the first \(i\) characters ending at rank \(j\). 'D' sums from larger ranks and 'I' from smaller ones, after ranks are compressed into \([0,i]\). The resulting recurrence is cubic.
We define \(f[i][j]\) as the number of permutations that satisfy the problem's requirements with the first \(i\) characters of the string ending with the number \(j\). Initially, \(f[0][0]=1\), and the rest \(f[0][j]=0\). The answer is \(\sum_{j=0}^n f[n][j]\).
Consider \(f[i][j]\), where \(j \in [0, i]\).
If the \(i\)th character \(s[i-1]\) is 'D', then \(f[i][j]\) can be transferred from \(f[i-1][k]\), where \(k \in [j+1, i]\). Since \(k-1\) can only be up to \(i-1\), we move \(k\) one place to the left, so \(k \in [j, i-1]\). Therefore, we have \(f[i][j] = \sum_{k=j}^{i-1} f[i-1][k]\).
If the \(i\)th character \(s[i-1]\) is 'I', then \(f[i][j]\) can be transferred from \(f[i-1][k]\), where \(k \in [0, j-1]\). Therefore, we have \(f[i][j] = \sum_{k=0}^{j-1} f[i-1][k]\).
The final answer is \(\sum_{j=0}^n f[n][j]\).
The time complexity is \(O(n^3)\), and the space complexity is \(O(n^2)\). Here, \(n\) is the length of the string.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | |
Solution 2: Prefix Sum Optimization
Thinking
Method 1 scans a range of \(k\) for every \(j\), and adjacent \(j\) share almost the same interval sum. A directional prefix sum evaluates \(\sum f[i-1][k]\) in constant time, dropping the time to quadratic without changing the state.
We can optimize the state transitions with prefix sums, reducing the time complexity to \(O(n^2)\). The space complexity remains \(O(n^2)\).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
Solution 3: Rolling Array Optimization
Thinking
\(f[i]\) depends only on \(f[i-1]\), so the second dimension of the table can be discarded. Roll a one-dimensional array and write the next layer from a running sum in the 'D' or 'I' direction, using linear extra space.
Based on Solution 2, we use a rolling array to reduce the space complexity to \(O(n)\). The time complexity remains \(O(n^2)\).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |