1. 程式人生 > >D-遞迴-LeetCode87-擾亂字串

D-遞迴-LeetCode87-擾亂字串

題目

給定一個字串 s1,我們可以把它遞迴地分割成兩個非空子字串,從而將其表示為二叉樹。

下圖是字串 s1 = "great" 的一種可能的表示形式。

    great
   /    \
  gr    eat
 / \    /  \
g   r  e   at
           / \
          a   t
在擾亂這個字串的過程中,我們可以挑選任何一個非葉節點,然後交換它的兩個子節點。

例如,如果我們挑選非葉節點 "gr" ,交換它的兩個子節點,將會產生擾亂字串 "rgeat" 。

    rgeat
   /    \
  rg    eat
 / \    /  \
r   g  e   at
           / \
          a   t
我們將 "rgeat” 稱作 "great" 的一個擾亂字串。

同樣地,如果我們繼續將其節點 "eat" 和 "at" 進行交換,將會產生另一個新的擾亂字串 "rgtae" 。

    rgtae
   /    \
  rg    tae
 / \    /  \
r   g  ta  e
       / \
      t   a
我們將 "rgtae” 稱作 "great" 的一個擾亂字串。

給出兩個長度相等的字串 s1 和 s2,判斷 s2 是否是 s1 的擾亂字串。

示例 1:

輸入: s1 = "great", s2 = "rgeat"
輸出: true
示例 2:

輸入: s1 = "abcde", s2 = "caebd"
輸出: false

思路

首先遍歷切分s1,與s1對應切分s2(切分s2分為兩種情況:首切和尾切,對應於題目的交換兩個子節點),切分的s1與s2繼續進行遞迴。遞迴終止條件s1.equals(s2) 或 s1.length()==2 && s1.charAt(0)==s2.charAt(1) && s1.charAt(1)==s2.charAt(0).
程式碼

class Solution {

    public boolean isScramble(String s1, String s2) {
        // 遞迴終止條件
        if(s1.equals(s2)){
            return true;
        }
        if(s1.length()==2 && s1.charAt(0)==s2.charAt(1) && s1.charAt(1)==s2.charAt(0) ){
            return true;
        }
        
        // 切分s1
        for(int i=1;i<s1.length();i++){
            String s1_l=s1.substring(0,i);
            String s1_r=s1.substring(i,s1.length());
            // 與s1對應切分s2
            String s2_l=s2.substring(0,i);
            String s2_r=s2.substring(i,s2.length());
            // 與s1對應切分s2
            String s2_ll=s2.substring(0,s1.length()-i);
            String s2_rr=s2.substring(s1.length()-i);
            
            if(isSame(s1_l,s2_l) && isSame(s1_r,s2_r)){
                if(isScramble(s1_l,s2_l) && isScramble(s1_r,s2_r)){
                    return true;
                }else{
                    // 這種切割方式不行,繼續執行外層for迴圈
                }
            }else if(isSame(s1_l,s2_rr) && isSame(s1_r,s2_ll)){
                if(isScramble(s1_l,s2_rr) && isScramble(s1_r,s2_ll)){
                    return true;
                }else{
                    // 這種切割方式不行,繼續執行外層for迴圈
                }
            }else{
                
            }
        }
        return false;
    }
    
    // 判斷str1與str2是否有完全相同的字元
    public static boolean isSame(String a,String b){
        char[] aa=a.toCharArray();
        char[] bb=b.toCharArray();
        Arrays.sort(aa);
        Arrays.sort(bb);
        return Arrays.equals(aa,bb);
    }
    
}