ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

力扣 题目97- 交错字符串

2022-07-23 18:03:49  阅读:121  来源: 互联网

标签:字符 s3 s2 s1 力扣 97 && 字符串 dp


题目

题解

首先就想的是动态规划法 用dp[i][j] ->即当s1取长度i s2取长度j时是否满足 需要注意的是当其中一个字符串为0 则另一个字符串必须全部与s3匹配才为1

int n1 = s1.size(), n2 = s2.size();
        vector<vector<bool>> dp(n1+1,vector<bool>(n2+1));
        dp[0][0] = true;
        for(int i=1;i<=n1;++i)
        {
            dp[i][0] = dp[i-1][0]&&(s1[i-1]==s3[i-1]);
        }
        for(int i=1;i<=n2;++i)
        {
            dp[0][i] = dp[0][i-1]&&(s2[i-1]==s3[i-1]);
        }
        for(int i=1;i<=n1;i++)
        {
            for(int j=1;j<=n2;j++)
            {
                dp[i][j] = dp[i-1][j]&&s1[i-1]==s3[i-1+j]||dp[i][j-1]&&s2[j-1]==s3[i-1+j];
            }
        }

 当然这是很容易想到的 动态规划 但是

进阶:您能否仅使用 O(s2.length) 额外的内存空间来解决它?

我们针对中心循环进行分析

 for(int i=1;i<=n1;i++)
        {
            for(int j=1;j<=n2;j++)
            {
                dp[i][j] = dp[i-1][j]&&s1[i-1]==s3[i-1+j]||dp[i][j-1]&&s2[j-1]==s3[i-1+j];
            }
        }

dp[i-1][j]意味着如果使用s1字符 那么之前的s1字符必须可行 同理dp[i][j-1]意味着如果这里使用s2字符 那么之前的s2字符必须可行

那么两个值是怎么来的呢 

dp[i-1][j]是来自当i=i-1时循环出来的 也就是上一层的循环

而dp[i][j-1]则是上一次循环得到的

我们发现 每一轮 层数最多只用到了他的上一层循环的值 而上两层之类的根本没用到!! 那么我们可以进行覆盖操作 只用一行容器 将新一轮的数据覆盖掉旧的数据 

然后 我们就使用dp[j] 去代表s2 就可以了 然后每一轮都覆盖一遍 dp[i-1][j]->dp[j] dp[i][j-1]->dp[j-1]

 for (int i = 1; i <= n1; i++) {
            for (int j = 0; j <= n2; j++) {
                //j=0时 意味着s2不取 只看s1是否和s3匹配
                //j!=0时 dp[j - 1] && s2[j - 1] == s3[i + j - 1]-> dp[j - 1]是上一次循环的结果即s2少一个字符 这里是否取s2的字符
                //dp[j] && s1[i - 1] == s3[i + j - 1] dp[j]是上一轮循环的结果即s1少一个字符 意思是这里是否取s1的字符
                dp[j] = j==0?  (dp[0] && s1[i - 1] == s3[i - 1]):
                      (dp[j - 1] && s2[j - 1] == s3[i + j - 1]) || (dp[j] && s1[i - 1] == s3[i + j - 1]);
            }
        }

代码

 1 #include<iostream>
 2 #include<string>
 3 #include<vector>
 4 using namespace std;
 5 class Solution {
 6 public:
 7     bool isInterleave(string s1, string s2, string s3) {
 8         if (s1.size() + s2.size() != s3.size()) {
 9             return false;
10         } 
11         int n1 = s1.size(), n2 = s2.size();
12         vector<bool> dp(vector<bool>(n2 + 1, false));
13         //s2为0时的情况
14         dp[0] = true;
15         //s1为0的情况 只看s2是否和s3匹配
16         for (int j = 1; j <= n2&& s2[j - 1] == s3[j - 1]; j++) {
17             dp[j] = true;
18         }
19         for (int i = 1; i <= n1; i++) {
20             for (int j = 0; j <= n2; j++) {
21                 //j=0时 意味着s2不取 只看s1是否和s3匹配
22                 //j!=0时 dp[j - 1] && s2[j - 1] == s3[i + j - 1]-> dp[j - 1]是上一次循环的结果即s2少一个字符 这里是否取s2的字符
23                 //dp[j] && s1[i - 1] == s3[i + j - 1] dp[j]是上一轮循环的结果即s1少一个字符 意思是这里是否取s1的字符
24                 dp[j] = j==0?  (dp[0] && s1[i - 1] == s3[i - 1]):
25                       (dp[j - 1] && s2[j - 1] == s3[i + j - 1]) || (dp[j] && s1[i - 1] == s3[i + j - 1]);
26             }
27         }
28         return dp[n2];
29     }
30 };
31 
32 int main() {
33     Solution sol;
34     string s1 = "aabcc"; 
35     string s2 = "dbbca";
36     string s3 = "aadbbcbcac";
37     bool result=sol.isInterleave(s1,s2,s3);
38     cout << result << endl;
39 
40 }
View Code

 

标签:字符,s3,s2,s1,力扣,97,&&,字符串,dp
来源: https://www.cnblogs.com/zx469321142/p/16512532.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有