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.

思路:简单的说,就是s1和s2是scramble的话,那么必然存在一个在s1上的长度l1,将s1分成s11和s12两段,同样有s21和s22。
那么要么s11和s21是scramble的并且s12和s22是scramble的;
要么s11和s22是scramble的并且s12和s21是scramble的。

如果要能通过OJ,还必须把字符串排序后进行剪枝,也就是变成char array sort一下后,两者应该相等,否则没必要继续进行判断,这样可以剪掉很多例子;

public class Solution {
    /**
     * @param s1: A string
     * @param s2: Another string
     * @return: whether s2 is a scrambled string of s1
     */
    public boolean isScramble(String s1, String s2) {
        if(s1 == null && s2 == null) return true;
        if(s1 == null || s2 == null || s1.length() != s2.length()) return false;
        
        if(s1.length() ==1){
            return s1.charAt(0) == s2.charAt(0);
        }
        
        if(!isValid(s1, s2)){
            return false;
        }
        
        for(int i = 0; i < s1.length(); i++) {
            String s11 = s1.substring(0,i);
            String s12 = s1.substring(i);
            String s21 = s2.substring(0,i);
            String s22 = s2.substring(i);
            String s23 = s2.substring(0, s2.length() - i);
            String s24 = s2.substring(s2.length() - i);
            
            if(isScramble(s11, s21) && isScramble(s12, s22)){
                return true;
            }
            
            if(isScramble(s11, s24) && isScramble(s12, s23)){
                return true;
            }
        }
        return false;
    }
    
    private boolean isValid(String s1, String s2) {
        char[] char1 = s1.toCharArray();
        char[] char2 = s2.toCharArray();
        
        Arrays.sort(char1);
        Arrays.sort(char2);
        
        String ns1 = new String(char1);
        String ns2 = new String(char2);
        
        if(!ns1.equals(ns2)){
            return false;
        }
        return true;
    }
}

DFS + memeory cache: 注意index表示的是在原来string里面的index,因为cache [i][j][k] 表达的意思是以s1 i 开始, s2 j 开始,长度为看的string是否是scramble;

public class Solution {
    /**
     * @param s1: A string
     * @param s2: Another string
     * @return: whether s2 is a scrambled string of s1
     */
    public boolean isScramble(String s1, String s2) {
        if(s1 == null && s2 == null) return true;
        if(s1 == null || s2 == null || s1.length() != s2.length()) return false;
        
        int n = s1.length();
        int[][][] cache = new int[n][n][n+1];
        return scrambleHelper(s1, 0, s2, 0, n, cache);
    }
    
    private boolean scrambleHelper(String s1, int start1, String s2, int start2, int k, int[][][] cache) {
        if(cache[start1][start2][k] == 1) {
            return true;
        }
        
        if(cache[start1][start2][k] == -1) {
            return false;
        }
        
        if(s1.length() != s2.length()){
            cache[start1][start2][k] = -1;
            return false;
        }
        
        if(s1.length() == 1){
            if(s1.charAt(0) == s2.charAt(0)){
                cache[start1][start2][k] = 1;
                return true;
            } else {
                cache[start1][start2][k] = -1;
                return false;
            }
        }
        
        for(int i = 1; i<s1.length(); i++) {
            String s11 = s1.substring(0,i);
            String s12 = s1.substring(i);
            String s21 = s2.substring(0,i);
            String s22 = s2.substring(i);
            String s23 = s2.substring(0,s1.length() - i);
            String s24 = s2.substring(s1.length() - i);
            
            if(scrambleHelper(s11, start1, s21, start2, i, cache) 
              && scrambleHelper(s12, start1+i, s22, start2 + i, k - i, cache)){
                  cache[start1][start2][k] = 1;
                  return true;
              }
             
            if(scrambleHelper(s11, start1, s24, start2+k-i, i, cache)
            && scrambleHelper(s12, start1+i, s23, start2, k-i, cache)){
                cache[start1][start2][k] = 1;
                return true;
            }
        }
        cache[start1][start2][k] = -1;
        return false;
    }
    
    private boolean isValid(String s1, String s2) {
        char[] char1 = s1.toCharArray();
        char[] char2 = s2.toCharArray();
        
        Arrays.sort(char1);
        Arrays.sort(char2);
        
        String ns1 = new String(char1);
        String ns2 = new String(char2);
        
        if(!ns1.equals(ns2)){
            return false;
        }
        return true;
    }
}

DP version:

dp[i][j][k] 代表了s1从i开始,s2从j开始,长度为k的两个substring是否为scramble

string。

有三种情况需要考虑:

1. 如果两个substring相等的话,则为true

2. 如果两个substring中间某一个点,左边的substrings为scramble string,

同时右边的substrings也为scramble string,则为true

3. 如果两个substring中间某一个点,s1左边的substring和s2右边的substring为scramble

string, 同时s1右边substring和s2左边的substring也为scramble

string,则为true
注意:  k<=n-Math.max(i,j) 
 boolean[][][] dp = new boolean [n][n][n+1]; 是N+1,因为dp[i][j][k] 代表的是s1从i开始,s2从j开始,长度为k的两个substring是否为scramble。

我们要判断dp[0][0][n] 所以,是n+1;

 

public class Solution {
    public boolean isScramble(String s1, String s2) {
        if(s1 == null || s2 == null) return false;
        
        if(s1.length() != s2.length()) return false;
        if(s1.length()==1 && s2.length()==1){
            return s1.charAt(0) == s2.charAt(0);
        }
        int n = s1.length();
        boolean[][][] dp = new boolean[n][n][n+1];
        for(int i=n-1; i>=0; i--){
            for(int j=n-1; j>=0; j--){
                for(int k=1; k<=n-Math.max(i,j);k++){
                    if(s1.substring(i,i+k).equals(s2.substring(j,j+k))){
                        dp[i][j][k]=true;
                    }else{
                        for(int l=1; l<k; l++){
                            if( (dp[i][j][l] && dp[i+l][j+l][k-l]) || (dp[i][j+k-l][l] && dp[i+l][j][k-l]) ){
                                dp[i][j][k]=true;
                                break;
                            }
                        }
                    }
                }
            }
        }
        return dp[0][0][n];
    }  
}

 

 

 

 

 

weixin073智慧旅游平台开发微信小程序+ssm后端毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
python017基于Python贫困生资助管理系统带vue前后端分离毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
weixin102旅游社交微信小程序+ssm后端毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值