zoukankan      html  css  js  c++  java
  • Leetcode: Scramble String

    Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrings recursively.
    
    Below is one possible representation of s1 = "great":
    
        great
       /    
      gr    eat
     /     /  
    g   r  e   at
               / 
              a   t
    To scramble the string, we may choose any non-leaf node and swap its two children.
    
    For example, if we choose the node "gr" and swap its two children, it produces a scrambled string "rgeat".
    
        rgeat
       /    
      rg    eat
     /     /  
    r   g  e   at
               / 
              a   t
    We say that "rgeat" is a scrambled string of "great".
    
    Similarly, if we continue to swap the children of nodes "eat" and "at", it produces a scrambled string "rgtae".
    
        rgtae
       /    
      rg    tae
     /     /  
    r   g  ta  e
           / 
          t   a
    We say that "rgtae" is a scrambled string of "great".
    
    Given two strings s1 and s2 of the same length, determine if s2 is a scrambled string of s1.

    难度:99

    这是个人觉得这是LeetCode中最难的动态规划的题目了,很难想,要进行一次三维动态规划,对于维护量的含义也比较讲究。如果用brute force,每次做切割,然后递归求解,是一个非多项式的复杂度,一般来说这不是面试官想要的答案。参考了一下Code Ganker的思路
    这其实是一道三维动态规划的题目,我们提出维护量res[i][j][n],其中i是s1的起始字符,j是s2的起始字符,而n是当前的字符串长度,res[i][j][len]表示的是以i和j分别为s1和s2起点的长度为len的字符串是不是互为scramble。
    有了维护量我们接下来看看递推式,也就是怎么根据历史信息来得到res[i][j][len]。判断这个是不是满足,其实我们首先是把当前s1[i...i+len-1]字符串劈一刀分成两部分,然后分两种情况:第一种是左边和s2[j...j+len-1]左边部分是不是scramble,以及右边和s2[j...j+len-1]右边部分是不是scramble;第二种情况是左边和s2[j...j+len-1]右边部分是不是scramble,以及右边和s2[j...j+len-1]左边部分是不是scramble。如果以上两种情况有一种成立,说明s1[i...i+len-1]和s2[j...j+len-1]是scramble的。而对于判断这些左右部分是不是scramble我们是有历史信息的,因为长度小于n的所有情况我们都在前面求解过了(也就是长度是最外层循环)。
    上面说的是劈一刀的情况,对于s1[i...i+len-1]我们有len-1种劈法,在这些劈法中只要有一种成立,那么两个串就是scramble的。
    总结起来递推式是res[i][j][len] = || (res[i][j][k]&&res[i+k][j+k][len-k] || res[i][j+len-k][k]&&res[i+k][j][len-k]) 对于所有1<=k<len,也就是对于所有len-1种劈法的结果求或运算。因为信息都是计算过的,对于每种劈法只需要常量操作即可完成,因此求解递推式是需要O(len)(因为len-1种劈法)。
    如此总时间复杂度因为是三维动态规划,需要三层循环,加上每一步需要线行时间求解递推式,所以是O(n^4)。虽然已经比较高了,但是至少不是指数量级的,动态规划还是有很大有事的,空间复杂度是O(n^3)。代码如下:

     1 public class Solution {
     2     public boolean isScramble(String s1, String s2) {
     3         if (s1 == null || s2 == null || s1.length() != s2.length()) return false;
     4         if (s1.length() == 0) return true;
     5         boolean[][][] check = new boolean[s1.length()][s2.length()][s1.length()+1];
     6         for (int i=0; i<s1.length(); i++) {
     7             for (int j=0; j<s2.length(); j++) {
     8                 check[i][j][1] = s1.charAt(i) == s2.charAt(j);
     9             }
    10         }
    11         for (int len=2; len<=s1.length(); len++) {
    12             for (int i=0; i+len-1<s1.length(); i++) {
    13                 for (int j=0; j+len-1<s2.length(); j++) {
    14                     for (int k=1; k<len; k++) {
    15                         check[i][j][len] |= check[i][j][k]&&check[i+k][j+k][len-k] || check[i][j+len-k][k]&&check[i+k][j][len-k];
    16                     }
    17                 }
    18             }
    19         }
    20         return check[0][0][s1.length()];
    21     }
    22 }
  • 相关阅读:
    WRF WPS预处理
    CVS安装
    Linux窗口最小化消失,任务栏上无法找到的解决方法
    NCARG安装配置出现error while loading shared libraries: libg2c.so.0问题额解决办法
    Netcdf安装
    Embedding R-generated Interactive HTML pages in MS PowerPoint(转)
    The leaflet package for online mapping in R(转)
    Some 3D Graphics (rgl) for Classification with Splines and Logistic Regression (from The Elements of Statistical Learning)(转)
    What does a Bayes factor feel like?(转)
    Weka算法介绍
  • 原文地址:https://www.cnblogs.com/EdwardLiu/p/4006636.html
Copyright © 2011-2022 走看看