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".)

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', then P[i] > P[i+1], and;
  • If S[i] == 'I', then P[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. 1 <= S.length <= 200
  2. S consists only of characters from the set {'D', 'I'}.

题目理解:

给定一个长度为n的字符串,仅由‘D’和‘I’组成,求符合要求的数组的数量,符合要求的数组是由0,1,2,...,n组成的数组,并且在出现‘D’的对应位置递减,在出现‘I’的对应位置递增

解题思路:

动态规划。举例:符合“DI”的数组只有1,0,2和2,0,1,要求符合“DID”的数组,我们需要在前面的两个数组中添加数字,如果我们添加num,那么就把数组中所有>=num的数字+1,这样,我们就可以把num添加到数组的最后,并且使得原数组仍然符合“DI”规则,可以看出来,如果是i位置是‘D’,那么我们可以添加所有小于等于最后一个数字的num,如果是‘I’,我们可以添加所有大于最后一个数字的num,所以我们总结地推公式如下:

dp[i][j]代表符合DI规则的前i个位置的由j结尾的数组的数目,那么可以求得递推公式:

dp[i][j] = 取和dp[i-1][k]            其中k>=j               DI字符串在i位置是‘D’

dp[i][j] = 取和dp[i-1][k]            其中k<j                 DI字符串在i位置是‘I’

由地推公式可以看出我们需要的是dp[i][0],dp[i][1],...,dp[i][j]的和,因此我们改变dp[i][j]的意义,dp[i][j]此时代表前述的和,做到这一点只需要在代码中添加dp[i][j]+=dp[i][j-1]

代码如下:

class Solution {
    public int numPermsDISequence(String S) {
    	int len = S.length();
    	char[] chs = S.toCharArray();
    	int[][] record = new int[len + 1][len + 1];
    	record[0][0] = 1;
    	int base = 1000000007;
    	for(int i = 1; i < len + 1; i++) {
    		char ch = chs[i - 1];
    		for(int j = 0; j <= i; j++) {
    			if(ch == 'D') {
    				record[i][j] += record[i - 1][i - 1];
    				if(j != 0)
    					record[i][j] -= record[i - 1][j - 1];
    			}
    			else if(ch == 'I') {
    				if(j != 0)
    					record[i][j] += record[i - 1][j - 1];
    			}
                record[i][j] %= base;
    			if(j > 0)
    				record[i][j] += record[i][j - 1];
    			record[i][j] %= base;
    		}
    		if(i < len)
    			record[i][i + 1] = record[i][i];
    	}
    	return (record[len][len] + base) % base;
    }
}

猜你喜欢

转载自blog.csdn.net/m0_37889928/article/details/82695805
DI
今日推荐