[leetcode]87. Scramble String字符串树形颠倒匹配

it2025-11-26  12

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 }

 

转载于:https://www.cnblogs.com/liuliu5151/p/9054224.html

相关资源:数据结构—成绩单生成器
最新回复(0)