leetcode97. 交错字符串(动态规划)

216 阅读1分钟

给定三个字符串 s1, s2, s3, 验证 s3 是否是由 s1 和 s2 交错组成的。

示例 1:

输入: s1 = “aabcc”, s2 = “dbbca”, s3 = “aadbbcbcac”
输出: true

解题思路

数组含义:dp[i][j]s1的前i个和s2的前j个能否组成字符串s3的前i+j长度的子串
状态转移: dp[i][j]=dp[i][j]||(dp[i-1][j]&&s1.charAt(i-1)==s3.charAt(loc))在(i-1,j)的基础上, 判断新加入的s1的i位置是否匹配s3.

代码

class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
        int n=s1.length(),m=s2.length();
        if(n+m!=s3.length()) return false;
        boolean[][] dp=new boolean[n+1][m+1];
        dp[0][0]=true;
        for(int i=0;i<=n;i++)
            for(int j=0;j<=m;j++)
            {
                int loc=i+j-1;
                if(i>0)
                    dp[i][j]=dp[i][j]||(dp[i-1][j]&&s1.charAt(i-1)==s3.charAt(loc));
                if(j>0)
                    dp[i][j]=dp[i][j]||(dp[i][j-1]&&s2.charAt(j-1)==s3.charAt(loc));

            }

        return dp[n][m];
    }
}

不一样的动态规划代码

class Solution {
     public static boolean isInterleave(String s1, String s2, String s3) {

        int n=s1.length(),m=s2.length();
        
        if(n+m!=s3.length()) return false;

        int[][] dp=new int[n+1][m+1];
        
        for(int i=1;i<=m;i++)
            if(s3.charAt(dp[0][i-1])==s2.charAt(i-1))
                dp[0][i]=dp[0][i-1]+1;
            else dp[0][i]=dp[0][i-1];

        for(int i=1;i<=n;i++)
            if(s3.charAt(dp[i-1][0])==s1.charAt(i-1))
                dp[i][0]=dp[i-1][0]+1;
            else dp[i][0]=dp[i-1][0];

        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {    if(s3.charAt(dp[i-1][j])==s1.charAt(i-1))
                    dp[i][j]= Math.max(Math.max(dp[i][j-1],dp[i-1][j]+1),dp[i][j]);
                if(s3.charAt(dp[i][j-1])==s2.charAt(j-1))
                    dp[i][j]= Math.max(Math.max(dp[i-1][j],dp[i][j-1]+1),dp[i][j]);

            }   
                     
                return  dp[n][m]==s3.length();
            

    }
}