D-遞迴-LeetCode87-擾亂字串
阿新 • • 發佈:2018-12-04
題目
給定一個字串 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); } }