• Interleaving String


    Interleaving String

    问题:

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

    思路:

      dfs肯定能解决 但是肯定会超时

      动态规划方程dp[i][j] == true only dp[i-1][j]&&s1.charAt(i)==s3.charAt(i+j) or dp[i][j-1] && s2.charAt(j) == s3.charAt(i+j)在刚了网上的答案后,才豁然开朗。

    参考答案后我写的代码:

    public class Solution {
        public boolean isInterleave(String s1, String s2, String s3) {
            if(s1 == null || s2 == null || s3 == null)  return true;
            if(s1.length() + s2.length() != s3.length()) return false;
            int m = s1.length();
            int n = s2.length();
            boolean[][] flag = new boolean[m+1][n+1];
            flag[0][0] = true;
            for(int i = 1; i <= m; i++)
            {
                if(flag[i-1][0])
                {
                    if(s1.substring(0,i).equals(s3.substring(0,i)))
                    {
                        flag[i][0] = true;
                    }
                }
            }
            for(int j = 1; j <= n; j++)
            {
                if(flag[0][j-1])
                {
                    if(s2.substring(0,j).equals(s3.substring(0,j)))
                    {
                        flag[0][j] = true;
                    }
                }
            }
            for(int i = 1; i <= m; i++)
            {
                for(int j = 1; j <= n; j++)
                {
                    if(flag[i][j-1])
                    {
                        if(s2.charAt(j-1) == s3.charAt(i+j-1))
                            flag[i][j] = true;
                    }
                    if(flag[i-1][j])
                    {
    
                        if(s1.charAt(i-1) == s3.charAt(i+j-1))
                            flag[i][j] = true;
                    }
                }
            }
            return flag[m][n];
        }
    }
    View Code

    别人代码1:(递归+memory)

    // Solution1: Recursion with memory
        public static boolean isInterleave1(String s1, String s2, String s3) {
            if (s1 == null || s2 == null || s3 == null) {
                return false;
            }
    
            int len1 = s1.length();
            int len2 = s2.length();
            int len3 = s3.length();
    
            // The length is not equal, just return false.
            if (len1 + len2 != len3) {
                return false;
            }
    
            int[][][] memory = new int[len1 + 1][len2 + 1][len3 + 1];
            for (int i = 0; i <= len1; i++) {
                for (int j = 0; j <= len2; j++) {
                    for (int k = 0; k <= len3; k++) {
                        memory[i][j][k] = -1;
                    }
                }
            }
    
            return recMemory(s1, 0, s2, 0, s3, 0, memory);
        }
    
        public static boolean recMemory(String s1, int index1, String s2,
                int index2, String s3, int index3, int[][][] memory) {
            int len1 = s1.length();
            int len2 = s2.length();
            int len3 = s3.length();
    
            if (index3 == len3 && index1 == len1 && index2 == len2) {
                return true;
            }
    
            if (memory[index1][index2][index3] != -1) {
                return memory[index1][index2][index3] == 1;
            }
    
            // 第一个字符,有2种可能:来自s1, 或是来自s2
            boolean ret = false;
            if (index1 < len1 && s1.charAt(index1) == s3.charAt(index3)) {
                ret = recMemory(s1, index1 + 1, s2, index2, s3, index3 + 1, memory);
            }
    
            // 如果不成功(首字母不来自于s1),尝试另一种可能
            if (!ret && index2 < len2 && s2.charAt(index2) == s3.charAt(index3)) {
                ret = recMemory(s1, index1, s2, index2 + 1, s3, index3 + 1, memory);
            }
    
            memory[index1][index2][index3] = ret ? 1 : 0;
            return ret;
        }
    
        // Solution2: Recursion with memory
        // 思考了一下看了一下过去的代码,发现其实我们用不到三维数组,因为len1 + len2 = len3,
        // 所以第三维根本可以省略嘛
        public static boolean isInterleave2(String s1, String s2, String s3) {
            if (s1 == null || s2 == null || s3 == null) {
                return false;
            }
    
            int len1 = s1.length();
            int len2 = s2.length();
            int len3 = s3.length();
    
            // The length is not equal, just return false.
            if (len1 + len2 != len3) {
                return false;
            }
    
            int[][] memory = new int[len1 + 1][len2 + 1];
            for (int i = 0; i <= len1; i++) {
                for (int j = 0; j <= len2; j++) {
                    memory[i][j] = -1;
                }
            }
    
            return recMemory2(s1, 0, s2, 0, s3, 0, memory);
        }
    View Code

    别人代码2:动态规划

    public class Solution {
        public boolean isInterleave1(String s1, String s2, String s3) {
            if (s1 == null || s2 == null || s3 == null) {
                return false;
            }
            
            int len1 = s1.length();
            int len2 = s2.length();
            int len3 = s3.length();
            
            if (len1 + len2 != len3) {
                return false;
            }
            
            boolean[][] D = new boolean[len1 + 1][len2 + 1];
            
            for (int i = 0; i <= len1; i++) {
                for (int j = 0; j <= len2; j++) {
                    D[i][j] = false;
                    if (i == 0 && j == 0) {
                        D[i][j] = true;
                    } else if (i == 0) {
                        D[i][j] = s2.charAt(j - 1) == s3.charAt(i + j - 1) && D[i][j - 1];
                    } else if (j == 0) {
                        D[i][j] = s1.charAt(i - 1) == s3.charAt(i + j - 1) && D[i - 1][j];
                    } else {
                        D[i][j] |= s2.charAt(j - 1) == s3.charAt(i + j - 1) && D[i][j - 1];
                        D[i][j] |= s1.charAt(i - 1) == s3.charAt(i + j - 1) && D[i - 1][j];
                    }
                }
            }
            
            return D[len1][len2];
        }
        
        public boolean isInterleave(String s1, String s2, String s3) {
            if (s1 == null || s2 == null || s3 == null) {
                return false;
            }
            
            int len1 = s1.length();
            int len2 = s2.length();
            int len3 = s3.length();
            
            if (len1 + len2 != len3) {
                return false;
            }
            
            boolean[][] D = new boolean[len1 + 1][len2 + 1];
            
            for (int i = 0; i <= len1; i++) {
                for (int j = 0; j <= len2; j++) {
                    D[i][j] = false;
                    if (i == 0 && j == 0) {
                        D[i][j] = true;
                        continue;
                    }
                    
                    if (i != 0) {
                        D[i][j] |= s1.charAt(i - 1) == s3.charAt(i + j - 1) && D[i - 1][j];
                    }
                    
                    if (j != 0) {
                        D[i][j] |= s2.charAt(j - 1) == s3.charAt(i + j - 1) && D[i][j - 1];
                    }
                }
            }
            
            return D[len1][len2];
        }
    }
    View Code

     学习之处:

    • 加入递归的想法很容易想啊,递归+memory和dp的方法时间复杂度一致,只是在空间上浪费了好多,在面试里面想不出来dp可以用dfs+memory解决不失为一个好的方法。
    • 字符串匹配常用的方法就是动态规划解决问题。
    • 对于两个字符串的匹配问题,就是母串从小到大 左右是否可以由子串组成
    • 对于说那个字符串的匹配问题,就是母串从小到大 左右是否由子串组成
    • 停!不知道动态规划方程式什么,可以先写dfs,写完dfs反推就可以得到动态规划方程了。(灵光一现的结论,明后天写代码尝试一下)
  • 相关阅读:
    Diablo3 英雄榜-显示用户的装备信息-Volley读取API的图片资源,使用MySingleton管理RequestQueue
    Diablo3英雄榜-使用Volley和Gson来处理暴雪API的Json数据
    Diablo3英雄榜-API分析
    《Android编程权威指南》-读书笔记(十一) 完善CriminalIntent
    《Android编程权威指南》-读书笔记(十)-从一个内涵段子开始第二个例子
    さらば、博客园よ
    Kotlin有点用力过猛了
    记一个耻辱
    备份一个省市区JSON数据
    博(wǒ)客(zì)园(jǐ)的排版真是丑毙了
  • 原文地址:https://www.cnblogs.com/sunshisonghit/p/4373094.html
Copyright © 2020-2023  润新知