• Interleaving String,交叉字符串,动态规划


    问题描述:

    Given s1s2s3, find whether s3 is formed by the interleaving of s1 and s2.

    For example,
    Given:
    s1 = "aabcc",
    s2 = "dbbca",

    When s3 = "aadbbcbcac", return true.
    When s3 = "aadbbbaccc", return false.

    算法分析:

    “When you see string problem that is about subsequence or matching, dynamic programming method should come to your mind naturally. ”

    此题可以用递归,也可以用动态规划。字符串的题一般用动态规划。

    dp[i][j]表示s1取前i位,s2取前j位,是否能组成s3的前i+j位

    举个列子,注意左上角那一对箭头指向的格子dp[1][1], 表示s1取第1位a, s2取第1位d,是否能组成s3的前两位aa

    从dp[0][1] 往下的箭头表示,s1目前取了0位,s2目前取了1位,我们添加s1的第1位,看看它是不是等于s3的第1位,( i + j 位)

    从dp[1][0] 往右的箭头表示,s1目前取了1位,s2目前取了0位,我们添加s2的第1位,看看它是不是等于s3的第1位,( i + j 位)

    首先第一个条件,新添加的字符,要等于s3里面对应的位( i + j 位),第二个条件,之前那个格子也要等于True

    举个简单的例子s1 = ab, s2 = c, s3 = bbc ,假设s1已经取了2位,c还没取,此时是False(ab!=bb),我们取s2的新的一位c,即便和s3中的c相等,但是之前是False,所以这一位也是False

    同理,如果s1 = ab, s2 = c, s3=abc ,同样的假设,s1取了2位,c还没取,此时是True(ab==ab),我们取s2的新的一位c,和s3中的c相等,且之前这一位就是True,此时我们可以放心置True (abc==abc)

    public class InterleavingString 
    {
    	//递归
    	public boolean isInterleave(String s1, String s2, String s3) 
    	{
    		if(s1.length() == 0)
    		{
    			return s2.equals(s3);//不能用==判断,否则出错
    		}
    		if(s2.length() == 0)
    		{
    			return s1.equals(s3);
    		}
    		if(s3.length() == 0)
    		{
    			return s1.length() + s2.length() == 0;
    		}
    		
    		
    		if(s1.charAt(0) == s3.charAt(0) && s2.charAt(0) != s3.charAt(0))
    		{
    			return isInterleave(s1.substring(1), s2, s3.substring(1));
    		}
    		else if(s2.charAt(0) == s3.charAt(0) && s1.charAt(0) != s3.charAt(0))
    		{
    			return isInterleave(s1, s2.substring(1), s3.substring(1));
    		}
    		else if(s1.charAt(0) == s3.charAt(0) && s2.charAt(0) == s3.charAt(0))
    		{
    			return isInterleave(s1.substring(1), s2, s3.substring(1)) || isInterleave(s1, s2.substring(1), s3.substring(1));
    		}
    		else
    		{
    			return false;
    		}
        }
    	
    	//动态规划
    	public boolean isInterleave2(String s1, String s2, String s3) 
    	{
    		if(s1 == null || s2 == null || s3 == null) return false;
    		if(s1.length() + s2.length() != s3.length()) return false;
    		boolean[][] dp = new boolean[s1.length()+1][s2.length()+1];
    		dp[0][0] = true;
    		for(int i = 1; i < s1.length() + 1; i ++)
    		{
    			if(s1.charAt(i-1) == s3.charAt(i-1) && dp[i-1][0])
    			{
    				dp[i][0] = true;
    			}
    		}
    		for(int j = 1; j < s2.length() + 1; j ++)
    		{
    			if(s2.charAt(j-1) == s3.charAt(j-1) && dp[0][j-1])
    			{
    				dp[0][j] = true;
    			}
    		}
    		
    		for(int i = 1; i < s1.length() + 1; i ++)
    		{
    			for(int j = 1; j < s2.length() + 1; j ++)
    			{
    				if(s2.charAt(j-1) == s3.charAt(i+j-1) && dp[i][j-1])
    				{
    					dp[i][j] = true;
    				}
    				if(s1.charAt(i-1) == s3.charAt(i+j-1) && dp[i-1][j])
    				{
    					dp[i][j] = true;
    				}
    			}
    		}
    		return dp[s1.length()][s2.length()];
    	}
    	
    	public static void main(String[] args) 
    	{
    		String s1 = "aabcc";
    		String s2 = "dbbca";
    		String s3 = "aadbbcbcac";
    		String s4 = "aadbbbaccc";
    		InterleavingString lv = new InterleavingString();
    		System.out.println(lv.isInterleave2(s1, s2, s3));
    		System.out.println(lv.isInterleave2(s1, s2, s4));
    	}
    }
    
  • 相关阅读:
    对 HTML 语义化的理解
    cookies,sessionStorage 和 localStorage 的区别
    display:none和visibility:hidden两者的区别
    页面导入样式时,使用link和@import有什么区别
    ES6之let和const
    v-if和v-show 的区别
    解决:Sass Loader has been initialised using an options object that does not ma tch the API schema.
    [转]javaweb学习总结(十四)——JSP原理
    [转]JavaWeb学习总结(十三)——使用Session防止表单重复提交
    [转]JavaWeb学习总结(十二)——Session
  • 原文地址:https://www.cnblogs.com/masterlibin/p/5835532.html
Copyright © 2020-2023  润新知