【递归到动态规划】:求字符串中所有子序列、求两字符串公共最长子序列

什么是子序列

子序列和子串不一样,字串的求法很简单,用两层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]));
}

动态规划版

求两字符串公共最长子序列

题解超详细

这个力扣题可以说是十分经典了,求两个字符串的公共最长子序列,用动态规划是很好解决的,如果想用递归求二者所有子序列然后再比较的话,会超时(我试过了😂)。里面的题解也十分经典,是一位大佬做的,太牛逼了。

class Solution {
    public int longestCommonSubsequence(String text1, String text2) {

        int table[][] = new int[text1.length() + 1][text2.length() + 1];

        for (int col=0; col<table[0].length; col++) {
            table[0][col] = 0;
        }

        for (int row=0; row<table.length; row++) {
            table[row][0] = 0;
        }

        for (int row=1; row<table.length;row++) {
            char ch1 = text1.charAt(row-1);
            for(int col=1; col<table[row].length; col++) {
                char ch2 = text2.charAt(col-1);
                if(ch1 == ch2) {
                    table[row][col] = table[row-1][col-1] + 1;
                } else {
                    table[row][col] = Math.max(table[row-1][col], table[row][col-1]);
                }
            }
        }

        int[] lastRow = table[table.length-1];
        return lastRow[lastRow.length-1];
    }
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值