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

    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.

    Example 1:

    Input: s1 = "great", s2 = "rgeat"
    Output: true
    

    Example 2:

    Input: s1 = "abcde", s2 = "caebd"
    Output: false

    扰乱字符串。题意是给一个string s1,这个string被表示成一个二叉树。在树的叶节点,每个字母会被分到二叉树的每一个最小的分支上自成一支。

    如上例子,great和rgeat是互为scramble string的。这题给的tag是DP但是DP的实现是三维的,几乎不可能在面试过程中完美实现。这里我给出的是递归解法,比较直观。

    时间O(n!) - 我其实不是很确定

    空间O(n) - 因为递归用到栈空间

    JavaScript实现

     1 /**
     2  * @param {string} s1
     3  * @param {string} s2
     4  * @return {boolean}
     5  */
     6 var isScramble = function(s1, s2) {
     7     if (s1 === s2) return true;
     8     const letters = new Array(128).fill(0);
     9     const a = 'a'.charCodeAt(0);
    10     for (let i = 0; i < s1.length; i++) {
    11         letters[s1.charCodeAt(i) - a]++;
    12         letters[s2.charCodeAt(i) - a]--;
    13     }
    14     for (let i = 0; i < 128; i++) {
    15         if (letters[i] !== 0) return false;
    16     }
    17     for (let i = 1; i < s1.length; i++) {
    18         if (isScramble(s1.substring(0, i), s2.substring(0, i)) && isScramble(s1.substring(i), s2.substring(i)))
    19             return true;
    20         if (
    21             isScramble(s1.substring(0, i), s2.substring(s2.length - i)) &&
    22             isScramble(s1.substring(i), s2.substring(0, s2.length - i))
    23         )
    24             return true;
    25     }
    26     return false;
    27 };

    Java实现 - 超时

     1 class Solution {
     2     public boolean isScramble(String s1, String s2) {
     3         // corner case
     4         if (s1 == null || s2 == null) {
     5             return false;
     6         }
     7         if (s1.equals(s2)) {
     8             return true;
     9         }
    10         // normal case
    11         int[] letters = new int[26];
    12         int len = s1.length();
    13         for (int i = 0; i < len; i++) {
    14             letters[s1.charAt(i) - 'a']++;
    15             letters[s2.charAt(i) - 'a']--;
    16         }
    17         for (int i = 0; i < 26; i++) {
    18             if (letters[i] != 0) {
    19                 return false;
    20             }
    21         }
    22         for (int i = 1; i < len; i++) {
    23             if (isScramble(s1.substring(0, i), s2.substring(0, i)) && isScramble(s1.substring(i), s2.substring(i))) {
    24                 return true;
    25             }
    26             if (isScramble(s1.substring(0, i), s2.substring(len - i)) && isScramble(s1.substring(i), s2.substring(0, len - i))) {
    27                 return true;
    28             }
    29         }
    30         return false;
    31     }
    32 }

    Java另一种带memorization的实现

     1 class Solution {
     2     HashMap<String, Boolean> map = new HashMap<>();
     3 
     4     public boolean isScramble(String s1, String s2) {
     5         StringBuilder sb = new StringBuilder();
     6         sb.append(s1);
     7         sb.append(s2);
     8         String key = sb.toString();
     9 
    10         if (map.containsKey(key)) {
    11             return map.get(key);
    12         }
    13 
    14         if (s1.equals(s2)) {
    15             map.put(key, true);
    16             return true;
    17         }
    18 
    19         int[] letters = new int[26];
    20         for (int i = 0; i < s1.length(); i++) {
    21             letters[s1.charAt(i) - 'a']++;
    22             letters[s2.charAt(i) - 'a']--;
    23         }
    24         for (int i = 0; i < 26; i++) {
    25             if (letters[i] != 0) {
    26                 map.put(key, false);
    27                 return false;
    28             }
    29         }
    30 
    31         for (int i = 1; i < s1.length(); i++) {
    32             if (isScramble(s1.substring(0, i), s2.substring(0, i)) && isScramble(s1.substring(i), s2.substring(i))) {
    33                 map.put(key, true);
    34                 return true;
    35             }
    36 
    37             if (isScramble(s1.substring(0, i), s2.substring(s1.length() - i))
    38                     && isScramble(s1.substring(i), s2.substring(0, s1.length() - i))) {
    39                 map.put(key, true);
    40                 return true;
    41             }
    42         }
    43 
    44         map.put(key, false);
    45         return false;
    46     }
    47 }

    LeetCode 题目总结

  • 相关阅读:
    分数的表示和运算
    用户管理
    DML,DDL
    索引
    sql语句执行顺序
    伪劣
    序列
    视图
    完整性约束
    ASP.NET MVC学习笔记(二)登陆验证
  • 原文地址:https://www.cnblogs.com/cnoodle/p/11762580.html
Copyright © 2011-2022 走看看