zoukankan      html  css  js  c++  java
  • 87. Scramble String

    问题:

    求给定的两个字符串S1和S2是否 S1能经过以下变换得到S2。

    若字符串长度为1,直接返回。

    • 从任意index,进行切分,pre和post两部分,
    • 可以选择:是否对这两部分进行交换。

    然后,再将分割后的两部分,分别作为对象字符串,重复上述两个操作。

    Example 1:
    Input: s1 = "great", s2 = "rgeat"
    Output: true
    Explanation: One possible scenario applied on s1 is:
    "great" --> "gr/eat" // divide at random index.
    "gr/eat" --> "gr/eat" // random decision is not to swap the two substrings and keep them in order.
    "gr/eat" --> "g/r / e/at" // apply the same algorithm recursively on both substrings. divide at ranom index each of them.
    "g/r / e/at" --> "r/g / e/at" // random decision was to swap the first substring and to keep the second substring in the same order.
    "r/g / e/at" --> "r/g / e/ a/t" // again apply the algorithm recursively, divide "at" to "a/t".
    "r/g / e/ a/t" --> "r/g / e/ a/t" // random decision is to keep both substrings in the same order.
    The algorithm stops now and the result string is "rgeat" which is s2.
    As there is one possible scenario that led s1 to be scrambled to s2, we return true.
    
    Example 2:
    Input: s1 = "abcde", s2 = "caebd"
    Output: false
    
    Example 3:
    Input: s1 = "a", s2 = "a"
    Output: true
     
    
    Constraints:
    
    s1.length == s2.length
    1 <= s1.length <= 30
    s1 and s2 consist of lower-case English letters.
    

      

    解法:DP(动态规划)

    1.确定【状态】:

    • 字符串s1的index:i
    • 字符串s2的index:j
    • 两字符串的长度:k

    2.确定【选择】:

    dp[i][j][k]:对s1[i~i+k-1]和s2[j~j+k-1],进行第q个位置分割:(q:1~k-1)

    • 任意位置切分能得到一个true,则可返回true。

    对于其中一个切分q:得到pre和post,以下两个操作,任意为true即可。

    • 不交换pre和post
      • 那么:s1_pre VS s2_pre 要满足题意 && s1_post VS s2_post 要满足题意
        • s1[i~i+q-1] vs s2[j~j+q-1] && s1[i+q~k] vs s2[j+q~k]
        • dp[i][j][q]                      && dp[i+q][j+q][k-q] 
    • 交换pre和post
      • 那么:s1_pre VS s2_post 要满足题意 && s1_post VS s2_pre 要满足题意
        • s1[i~i+q-1] vs s2[j+k-q~k] && s1[i+q~k] vs s2[j~j+k-q-1]
        • dp[i][j+k-q][q]                 && dp[i+q][j][k-q] 

    3. dp[i][j][k]的含义:

    字符串s1[i~i+k-1]   VS   字符串s2[j~j+k-1]

    这两个子串是符合题意的字符串。(S1可以通过题目所述变换得到S2)

    4. 状态转移:

    dp[i][j][k]=

    for all q:1~k-1 : OR{

    • dp[i][j][q]                      && dp[i+q][j+q][k-q] 
    • dp[i][j+k-q][q]                 && dp[i+q][j][k-q] 
    • }

    5. base case:

    • dp[i][j][1]= (s1[i]==s2[j]?true:false)

    代码参考:

     1 class Solution {
     2 public:
     3     //dp[i][j][k]: strlen = k
     4     //            s1[i~i+k-1] vs s2[j~j+k-1]
     5     //            they are Scramble? True or False
     6     //opt: divide at q:(1~k-1) OR { case_1 or case_2 } (for all q)
     7     //case_1: not swap:
     8     //      s1_pre vs s2_pre (len:q)   && s1_post vs s2_post (len:k-q)
     9     //      s1[i~i+q-1] vs s2[j~j+q-1] && s1[i+q~k] vs s2[j+q~k]
    10     //    ->dp[i][j][q]                && dp[i+q][j+q][k-q] 
    11     //case_2: swap: divide pos:s1[q], s2[k-q]
    12     //      s1_pre vs s2_post (len:q)  && s1_post vs s2_pre (len:k-q)
    13     //      s1[i~i+q-1] vs s2[j+k-q~k] && s1[i+q~k] vs s2[j~j+k-q-1]
    14     //    ->dp[i][j+k-q][q]                && dp[i+q][j][k-q] 
    15     //base:
    16     //dp[i][j][1] = (if s1[i]==s2[j] then true others false)
    17     bool isScramble(string s1, string s2) {
    18         int len = s1.length();
    19         vector<vector<vector<bool>>> dp(len, 
    20                                         vector<vector<bool>>(len,
    21                                                              vector<bool>(len+1, false)));
    22         for(int k=1; k<=len; k++) {
    23             for(int i=0; i<=len-k; i++) {
    24                 for(int j=0; j<=len-k; j++) {
    25                     if(k==1) dp[i][j][k] = (s1[i]==s2[j]?true:false);
    26                     else {
    27                         for(int q=1; q<k && !dp[i][j][k]; q++) {
    28                             dp[i][j][k] = (dp[i][j][q] && dp[i+q][j+q][k-q]) 
    29                                 || (dp[i][j+k-q][q] && dp[i+q][j][k-q]);
    30                         }
    31                     }
    32                 }
    33             }
    34         }
    35         return dp[0][0][len];
    36     }
    37 };
  • 相关阅读:
    sql server数据库备份与复制(1):通过复制.mdf和.ldf文件实现数据转移
    SQL SERVER数据库备份与复制(4):让SQL SERVER自动备份方法一
    js 日历控件
    SQL SERVERa数据备份与复制(2):直接复制MDF文件和使用SQL的备份之间的区别
    mysql 插入中文乱码解决方案
    sql server数据库注意点
    SQL SERVERR数据库备份与复制(5):自动备份的SP
    mysql数据备份或转移(1)——通过数据复制实现转移
    SQL Server数据库备份与复制(3):从备份到转移的几种方法方法
    SQLSERVER数据存储内幕
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14566968.html
Copyright © 2011-2022 走看看