zoukankan      html  css  js  c++  java
  • [leetcode]87. 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

    题意:

    对于一个字符串,若通过一些列树形颠倒(确定一点后,前后子串交换)得到一个新的字符串,则互为Scramble String

    思路:

    这道题面试很低频,因为若要dp解,则需三维dp,难度很高不适合面试

    直接用递归,观察规律:

    若s1 和 s2 长度都为1 : 两字符串必须完全相当

    若s1 和 s2 长度都为2: 则当s1 = "ab"时, s2 = "ab" || "ba"

    若s1 和 s2 长度都为3: 将 s1 分成 s1Left 和 s1Right两部分

                                        s2 分成 s2Left 和 s2Right 两部分

                                      则 ( s1Left  isScrambled s2Left  && s1Right isScrambled s2Right ) 或者  (s1Left  isScrambled s2Right && s1Right isScrambled s2Left  ) 

    如图,

    所以,

    先判断s1和s2是否是valid anagram (变位词): 意味着两个字符串长度一致,互相只是各个字符串变换了位置

    再递归生成s1的左边、右边,s2 的左边、右边

    递归出口: s1等于s2 return true

    代码:

     1 class Solution {
     2     public boolean isScramble(String s1, String s2) {
     3          // corner
     4         if(s1.length() != s2.length() || s1 == null || s2 == null) return false;
     5         // recursion 出口
     6         if(s1.equals(s2)) return true; // 一定要加,否则recursion 没有出口
     7         // valid anagram or not 
     8         int[]map = new int[256];
     9         for(int i = 0; i < s1.length(); i++){
    10             map[s1.charAt(i)] ++;
    11             map[s2.charAt(i)] --;
    12         } 
    13         for(int i : map){
    14             if( i != 0){
    15                 return false;
    16             }
    17         }
    18         // recursion 
    19         for(int i = 1; i < s1.length(); i++){ 
    20         if(isScramble(s1.substring(0,i), s2.substring(0,i)) && isScramble(s1.substring(i), s2.substring(i))) return true;
    21         if(isScramble(s1.substring(0,i), s2.substring(s2.length()-i)) && isScramble(s1.substring(i), s2.substring(0, s2.length()-i))) return true;
    22               
    23         } 
    24        return false;
    25     }
    26     
    27 }
  • 相关阅读:
    微信小程序入门
    webpack
    模块化开发(1)
    HTML5表单
    移动端入门
    MySQL
    js面向对象与PHP面向对象总结
    PHP
    Git指令
    Redux
  • 原文地址:https://www.cnblogs.com/liuliu5151/p/9054224.html
Copyright © 2011-2022 走看看