• Leetcode | Interleaving String


    Given s1, s2, s3, 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.

    用回溯TLE,所以想用dp来做。

    为了方便计算,从尾往前扫。dp[i][j]表示s3[i+j...n3-1]是不是s1[i...n1-1]和s2[j...n2-1]的interleaving。

    如果s3[i+j]=s1[i],那么s[i+j...n3-1]是不是interleaving,取决于s1[i+1...n1-1]和s2[j...n2-1]是不是合法的interleaving。

    如果s[i+1]=s2[j],同理,取决于取决于s1[i...n1-1]和s2[j+1...n2-1]是不是合法的interleaving。

    以上只要有一种情况满足就可以了。

    dp[i][j] = ((s3[i + j] == s1[i] && dp[i + 1][j]) || (s3[i + j] == s2[j] && dp[i][j + 1]));

    关于初始值:

    i=n1的时候,也就是s1=“”,空串和s2是不是一个合法的interleaving,s2后半段和s3后半段都相同的部分全部为true。j=n2同理。

    当然也可以认为,dp[i][n2] = (s3[i + n2] == s1[i] && dp[i+1][n2]);dp[n1][i] = (s3[i + n1] == s2[i] && dp[n1][i + 1]);

     1 class Solution {
     2 public:
     3     bool isInterleave(string s1, string s2, string s3) {
     4        int n1 = s1.length(), n2 = s2.length(), n3 = s3.length();
     5        if (n1 + n2 != n3) return false;
     6        
     7        vector<vector<bool> > dp(n1 + 1, vector<bool>(n2 + 1, false));
     8        dp[n1][n2] = true;
     9        for (int i = n1 - 1; i >= 0; --i) {
    10            dp[i][n2] = (s3[i + n2] == s1[i] && dp[i+1][n2]);
    11        }
    12        for (int i = n2 - 1; i >= 0; --i) {
    13            dp[n1][i] = (s3[i + n1] == s2[i] && dp[n1][i + 1]);
    14        }
    15         
    16        for (int i = n1 - 1; i >= 0; --i) {
    17            for (int j = n2 - 1; j >= 0; --j) {
    18                dp[i][j] = ((s3[i + j] == s1[i] && dp[i + 1][j])
    19                             || (s3[i + j] == s2[j] && dp[i][j + 1])); 
    20            }
    21        }
    22        
    23 
    24        return dp[0][0];
    25     }
    26 };

    因为只用到上一行当前位置和当前行后一个位置,所以二维dp可以再优化成一维。

     1 class Solution {
     2 public:
     3     bool isInterleave(string s1, string s2, string s3) {
     4        int n1 = s1.length(), n2 = s2.length(), n3 = s3.length();
     5        if (n1 + n2 != n3) return false;
     6        
     7        vector<bool> dp(n2 + 1, false);
     8        dp[n2] = true;
     9 
    10        for (int i = n2 - 1; i >= 0; --i) {
    11            dp[i] = (s3[i + n1] == s2[i] && dp[i + 1]);
    12        }
    13         
    14        for (int i = n1 - 1; i >= 0; --i) {
    15            dp[n2] = (s3[i + n2] == s1[i] && dp[n2]);
    16            for (int j = n2 - 1; j >= 0; --j) {
    17                dp[j] = ((s3[i + j] == s1[i] && dp[j])
    18                             || (s3[i + j] == s2[j] && dp[j + 1])); 
    19            }
    20        }
    21        
    22 
    23        return dp[0];
    24     }
    25 };
  • 相关阅读:
    关于document.body.scrollTop用法
    set回顾
    用户登录与注册
    编写通讯录2
    利用字典的特性编写一个通讯录
    shelve模块
    shutil模块
    列表的拓展
    随机生成验证码2
    递归与欧几里得算法结合求最大公约数
  • 原文地址:https://www.cnblogs.com/linyx/p/3724348.html
Copyright © 2020-2023  润新知