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 };
  • 相关阅读:
    210111做个期望值低的人
    error_1 springboot `com.mysql.jdbc.Driver'问题
    error_2 springboot mysql时区设置
    17_springboot Restful风格
    15_JSON springboot
    13_springboot文件上传
    12_springboot myBatis crud
    11_springboot JPA crud
    Swagger导出MarkDown
    Docker 使用中的一些问题
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14566968.html
Copyright © 2011-2022 走看看