首页 > 编程语言 >(算法)交错字符串————<动态规划>

(算法)交错字符串————<动态规划>

时间:2024-11-01 18:17:16浏览次数:3  
标签:s3 s2 s1 区间 算法 交错 字符串 dp

1. 题⽬链接:97.交错字符串

2. 题⽬描述:

3. 解法(动态规划):

算法思路:

对于两个字符串之间的dp 问题,我们⼀般的思考⽅式如下:

        i. 选取第⼀个字符串的[0, i] 区间以及第⼆个字符串的[0, j] 区间当成研究对象,结合题⽬的要求来定义「状态表⽰」;

        ii. 然后根据两个区间上「最后⼀个位置的字符」,来进⾏「分类讨论」,从⽽确定「状态转移 ⽅程」。 我们可以根据上⾯的策略,解决⼤部分关于两个字符串之间的dp 问题。 

这道题⾥⾯空串是有研究意义的,因此我们先预处理⼀下原始字符串,前⾯统⼀加上⼀个占位符: s1 = " " + s1, s2 = " " + s2, s3 = " " + s3 。

1. 状态表⽰:

dp[i][j] 表⽰字符串s1 中[1, i] 区间内的字符串以及s2 中[1, j] 区间内的字符串,能否拼接成s3 中[1, i + j] 区间内的字符串。

2. 状态转移⽅程:

先分析⼀下题⽬,题⽬中交错后的字符串为s1 + t1 + s2 + t2 + s3 + t3...... ,看 似⼀个s ⼀个t 。实际上s1 能够拆分成更⼩的⼀个字符,进⽽可以细化成s1 + s2 + s3 + t1 + t2 + s4...... 。 也就是说,并不是前⼀个⽤了s 的⼦串,后⼀个必须要⽤t 的⼦串。这⼀点理解,对我们的状 态转移很重要。 继续根据两个区间上「最后⼀个位置的字符」,结合题⽬的要求,来进⾏「分类讨论」:

        i. 当s3[i + j] = s1[i] 的时候,说明交错后的字符串的最后⼀个字符和s1 的最后⼀ 个字符匹配了。那么整个字符串能否交错组成,变成: s1 中[1, i - 1] 区间上的字符串以及s2 中[1, j] 区间上的字符串,能够交 错形成s3 中[1, i + j - 1] 区间上的字符串,也就是dp[i - 1][j] ;此时dp[i][j] = dp[i - 1][j]

        ii. 当s3[i + j] = s2[j] 的时候,说明交错后的字符串的最后⼀个字符和s2 的最后 ⼀个字符匹配了。那么整个字符串能否交错组成,变成: s1 中[1, i] 区间上的字符串以及s2 中[1, j - 1] 区间上的字符串,能够交 错形成s3 中[1, i + j - 1] 区间上的字符串,也就是dp[i][j - 1] ;

        iii. 当两者的末尾都不等于s3 最后⼀个位置的字符时,说明不可能是两者的交错字符串。 

上述三种情况下,只要有⼀个情况下能够交错组成⽬标串,就可以返回true 。因此,我们可以 定义状态转移为: dp[i][j] = (s1[i - 1] == s3[i + j - 1] && dp[i - 1][j]) || (s2[j - 1] == s3[i + j - 1] && dp[i][j - 1]) 只要有⼀个成⽴,结果就是true 。

3. 初始化:

由于⽤到i - 1 ,j - 1 位置的值,因此需要初始化「第⼀个位置」以及「第⼀⾏」和「第⼀ 列」。

        ◦ 第⼀个位置: dp[0][0] = true ,因为空串+空串能够构成⼀个空串。

        ◦ 第⼀⾏: 第⼀⾏表⽰s1 是⼀个空串,我们只⽤考虑s2 即可。因此状态转移之和s2 有关: dp[0][j] = s2[j - 1] == s3[j - 1] && dp[0][j - 1] , j 从1 到n ( n 为s2 的⻓度)

        ◦ 第⼀列: 第⼀列表⽰s2 是⼀个空串,我们只⽤考虑s1 即可。因此状态转移之和s1 有关: dp[i][0] = s1[i - 1] == s3[i - 1] && dp[i - 1][0] , i 从1 到m ( m 为s1 的⻓度)

4. 填表顺序:

根据「状态转移」,我们需要「从上往下」填每⼀⾏,每⼀⾏「从左往右」。

5. 返回值:

根据「状态表⽰」,我们需要返回dp[m][n] 的值。

C++算法代码: 

class Solution 
{
public:
    bool isInterleave(string s1, string s2, string s3) 
    {
        int m=s1.size(),n=s2.size();
        //优化
        if(m+n!=s3.size())
        {
            return false;
        }
        s1=" "+s1;
        s2=" "+s2;
        s3=" "+s3;
        //建表
        vector<vector<bool>>dp(m+1,vector<bool>(n+1));
        //初始化
        dp[0][0]=true;
        for(int i=1;i<=m;i++)
        {
            if(s1[i]!=s3[i])
            {
                break;
            }
            dp[i][0]=true;
        }
        for(int i=1;i<=n;i++)
        {
            if(s2[i]!=s3[i])
            {
                break;
            }
            dp[0][i]=true;
        }
        //填表
        for(int i=1;i<=m;i++)
        {
            for(int j=1;j<=n;j++)
            {
                dp[i][j] = (s1[i] == s3[i + j] && dp[i - 1][j])|| (s2[j] == s3[i + j] && dp[i][j - 1]);
            }
        }
        //返回值
        return dp[m][n];
    }
};

Java算法代码:

class Solution
{
	public boolean isInterleave(String s1, String s2, String s3)
	{
		// 1. 创建 dp 表 
		// 2. 初始化 
		// 3. 填表 
		// 4. 返回值 
		int m = s1.length(), n = s2.length();
		if (m + n != s3.length()) return false; // 处理下边界条件 
		s1 = " " + s1; s2 = " " + s2; s3 = " " + s3;
		boolean[][] dp = new boolean[m + 1][n + 1];
		dp[0][0] = true; // 初始化 
		for (int j = 1; j <= n; j++) // 初始化第⼀⾏ 
			if (s2.charAt(j) == s3.charAt(j)) dp[0][j] = true;
			else break;
		for (int i = 1; i <= m; i++) // 初始化第⼀列 
			if (s1.charAt(i) == s3.charAt(i)) dp[i][0] = true;
			else break;

		for (int i = 1; i <= m; i++)
			for (int j = 1; j <= n; j++)
				dp[i][j] = (s1.charAt(i) == s3.charAt(i + j) && dp[i - 1][j])
				|| (s2.charAt(j) == s3.charAt(i + j) && dp[i][j - 1]);
		return dp[m][n];
	}
}

标签:s3,s2,s1,区间,算法,交错,字符串,dp
From: https://blog.csdn.net/2301_79580018/article/details/143438027

相关文章

  • 代码随想录算法训练营第三十三天|Day33 动态规划
    62.不同路径https://programmercarl.com/0062.%E4%B8%8D%E5%90%8C%E8%B7%AF%E5%BE%84.html视频讲解:https://www.bilibili.com/video/BV1ve4y1x7Eu思路int**initDP(intm,intn){int**dp=(int**)malloc(sizeof(int*)*m);inti,j;for(i=0;i<......
  • 排序算法:从原理到 Java 实现
    文章目录排序算法:从原理到Java实现一、引言二、常见排序算法原理及Java实现(一)冒泡排序(BubbleSort)(二)选择排序(SelectionSort)(三)插入排序(InsertionSort)(四)快速排序(QuickSort)(五)归并排序(MergeSort)(六)堆排序(HeapSort)三、性能比较与分析(一)时间复杂度(二)空间复杂度(三)稳定......
  • printf打印带中文的字符串不乱码的编译注意事项
    在Windows环境下编译:MSC编译器MSC编译器会把源程序转换为当前代码页编码的源程序。1、如果源文件是ANSI(当前代码页936)编码,直接编译;2、如果源文件是不带BOM的UTF-8,则编译的时候需要加-source-charset:UTF-8;3、如果源文件是带BOM的UTF-8、UTF-16LE、UTF-16BE,直接进行编译。G......
  • 人脸识别算法 - 专利1分析
      专利CN117576758A中说明了一种人脸识别算法的整体识别流程,本文将对这篇文章进行详细讲解,并说明有创造性的算法部分。  前置知识:人脸识别   人脸识别技术是一种通过计算机技术和模式识别算法来识别和验证人脸的技术。它能够用于识别人脸的身份、检测人脸的表情......
  • 车辆违停视频分析网关AI智能分析车辆检测算法在车辆智能管控场景中的应用
    随着人工智能技术的快速发展,视频AI智能分析网关在车辆检测与车牌识别领域的应用越来越广泛。尤其在智能交通管理领域,这一技术正发挥着至关重要的作用。视频分析网关AI智能分析车辆检测算法,基于深度学习技术,通过训练大量标注数据,实现了对视频中车辆的快速、准确检测与车牌识别。这......
  • 离岗检测视频分析网关AI智能分析在岗离岗检测算法的原理与应用
    在岗离岗检测算法是一项利用计算机视觉和深度学习技术的应用,它通过解析监控视频流来辨认和追踪人员,进而确定他们是否处于特定的工作区域内。算法网关视频分析网关在众多领域中都有着重要的应用价值,特别是在那些需要确认员工在岗状态的场景中,例如在工厂、仓库、银行、医院等场所。......
  • 智慧工地算法视频分析服务器区域入侵检测AI视频分析技术在煤矿的实战应用
    智慧煤矿中应用的智慧矿山算法视频分析服务器,依托于人工智能算法对矿井下的视频资料进行深入的分析与处理。这项技术能够利用图像识别和模式识别等方法,实时监测视频中的重要信息,包括工作人员的行为、设备运行状况以及环境指标等,为煤矿的安全作业和预防事故提供了强有力的技术支......
  • 算法工程师大致是做什么的
    算法工程师通常致力于研究、开发、优化算法,让计算机能够解决复杂问题。其主责包括算法设计与分析、数据挖掘、人工智能及深度学习等。其中,算法优化尤为重要,强化程序效率与准确性。详细探讨其中一个环节——算法优化,此类工程师应用数学与逻辑分析,确保算法更加高效、稳定。一、算法......
  • 洛谷题单指南-字符串-P3369 【模板】普通平衡树
    原题链接:https://www.luogu.com.cn/problem/P3369题意解读:平衡树的基本操作,模版题。解题思路:1、二叉搜索树-BST二叉搜索树满足这样的性质:每一个节点的权值大于它的左儿子,小于它的右儿子。对BST进行中序遍历,将得到一个从小到大的有序序列,因此BST是为了维护一个有序序列的动态......
  • ”回溯算法“框架及练习题
    @目录一、回溯算法是什么?二、框架如下:本人其他文章链接一、回溯算法是什么?结论:回溯=穷举解决一个回溯问题,实际上就是一个决策树的遍历过程路径:就是已经做出的选择选择列表:就是你当前可以做出的选择结束条件:就是basecase条件,也就是临界条件二、框架如下:框架如下:resu......