最公共长子序列的长度

博客探讨了如何找到两个序列之间的最长公共子序列,并强调了其最大长度问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最长公共子序列的最大长度

/**
 * 最长公共子序列的长度
 * 题目描述
 * 给定2个无序序列 s1 s2, 求2个字符串的最长公共子序列,子序列的元素都得在s1,s2中找到,并且与s1 s2 的顺序相同
 * 解题思路:
 * 动态规划
 * 对s1左边的i个和s2左边的j个字符分别讨论,求它们能够组成的最长公共子序列的长度,因为涉及到2个自变量,所以应该维护一个二维数组maxLen[i][j]
 * 那么怎么求maxLen[i][j]就是关键,需要求得其递推公式:maxLen[i][j]状态与它的前面的状态的关系,才能使用循环分别讨论i j
 * maxLen[0][j] = 0
 * maxLen[i][0] = 0 
 * maxLen[i][j] = 
 * {
 * 	1) maxLen[i-1][j-1]+1 (s1[i-1] == s2[j-1])  字符串最左边的字符是s[0]
 *  2) Max{maxLen[i][j-1], maxLen[i-1][j]} (s1[i-1] != s2[j-1])
 * }
 */
package dp;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
	static char[] c1 = null;
	static char[] c2 = null;
	static int[][] maxLen = null;
	public static void main(String[] args){
		/**
		 * 测试结果
		 * 输入:
		 * abcfbc abfcab
		 * 输出:
			4
			输入:
			programming contest
			输出: 
			2
			输入:
			abcd mnp
			输出:
			0

		 */
		Scanner in = new Scanner(System.in);
		while(in.hasNext()){
			c1 = in.next().toCharArray();
			c2 = in.next().toCharArray();
			//动态规划的二维数组申请空间
			maxLen = new int[c1.length+1][c2.length+1];
			//初始化边界条件
			for(int j = 1; j <= c2.length; j++){
				maxLen[0][j] = 0;
			}
			for(int i = 1; i <= c1.length; i++){
				maxLen[i][0] = 0;
			}
			//分别讨论s1的左边i个,s2的左边j个 能组成的最长公共子序列的长度maxLen[i][j],使用递推公式循环处理
			for(int i = 1; i <= c1.length; i++){//s1的左边i个
				for(int j = 1; j <= c2.length; j++){//s2的左边j个
					if(c1[i-1] == c2[j-1])
						maxLen[i][j] = maxLen[i-1][j-1] + 1; //意味着s1[i] s2[j]同时为最长公共子序列的最后一个已经确定,那么当前状态可有前一状态maxLen[i-1][j-1]加上1求出
					else
						maxLen[i][j] = Math.max(maxLen[i][j-1], maxLen[i-1][j]);//意味着s[i]与s[j]至少有一个不是最长公共子序列的最后一个字符,那么可以选择性的干掉其中一个,
					//得到前一状态,再由前边的状态的最大情况推出当前状态
				}
			}
			System.out.println(maxLen[c1.length][c2.length]);
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值