【递归到动态规划】:求字符串中所有子序列

什么是子序列

子序列和子串不一样,字串的求法很简单,用两层for循环即可得到。比如absv这个字符串,他的字串全部就是a,ab,abs,absv,b,bs,bsv,s,sv,v,和空,但是它的子序列选择的方式更多,中间可以有空隔,比如asv也是其子序列,所以求子序列,我们可以用递归,类似二叉树的求法,每一个位置都有两个状态,选与不选

代码

递归法

 // str 固定参数
// 来到了str[index]字符,index是位置
// str[0..index-1]已经走过了!之前的决定,都在path上
// 之前的决定已经不能改变了,就是path
// str[index....]还能决定,之前已经确定,而后面还能自由选择的话,
// 把所有生成的子序列,放入到ans里去
public static void process1(char[] str, int index, List<String> ans, String path) {
    
    
	if (index == str.length) {
    
    
		ans.add(path);
		return;
	}
	// 没有要index位置的字符
	process1(str, index + 1, ans, path);
	// 要了index位置的字符
	process1(str, index + 1, ans, path + String.valueOf(str[index]));
}

动态规划版

public static int dp(String s) {
    
    
	if (s == null || s.length() == 0) {
    
    
		return 0;
	}
	char[] str = s.toCharArray();
	int N = str.length;
	int[] dp = new int[N + 1];
	dp[N] = 1;
	for (int i = N - 1; i >= 0; i--) {
    
    
		if (str[i] != '0') {
    
    
			int ways = dp[i + 1];
			if (i + 1 < str.length && (str[i] - '0') * 10 + str[i + 1] - '0' < 27) {
    
    
				ways += dp[i + 2];
			}
			dp[i] = ways;
		}
	}
	return dp[0];
}

猜你喜欢

转载自blog.csdn.net/VanGotoBilibili/article/details/115206342