1. 程式人生 > 實用技巧 >leetcode刷題筆記八十七題 擾亂字串

leetcode刷題筆記八十七題 擾亂字串

leetcode刷題筆記八十七題 擾亂字串

源地址:87. 擾亂字串

問題描述:

給定一個字串 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

/**
題解參考https://leetcode-cn.com/problems/scramble-string/solution/miao-dong-de-qu-jian-xing-dpsi-lu-by-sha-yu-la-jia/
使用區間型dp進行處理,依題意, str可被分割為str1和str2, tStr可被分割為tStr1和tStr2.滿足str1 == tStr1 且 str2 == tStr2 情況或者 str1 == tStr2 且 str2 == tStr1時,認為可返回true
使用dp(i)(j)(k)(h) 表示str(i,j) 與 tStr(k,h) 是否成立
但由於要求str.length == tStr.length,將dp陣列簡化為dp(i)(j)(len)
初始狀態 dp(i)(j)(1) == str(i) == tStr(j)
狀態轉換方程 dp(i)(j)(len) == (dp(i)(j)(k) && dp(i+k)(j+k)(len-k)) || (dp(i)(j+len-k)(k) && dp(i+k)(j)(len-k))
時間複雜度:O(n^4)
空間複雜度:O(n^3)
*/
import util.control.Breaks._
object Solution {
    def isScramble(s1: String, s2: String): Boolean = {
        //要求str與tStr長度一致
        val str1Length = s1.length
        val str2Length = s2.length
        if(str1Length != str2Length) return false
		
        val dp = Array.ofDim[Boolean](str1Length, str1Length, str1Length+1)
		
        for(i <- 0 to str1Length-1){
            for(j <- 0 to str1Length-1){
                if(s1(i) == s2(j))  dp(i)(j)(1) = true
                else dp(i)(j)(1) = false
            }
        }

        for(len <- 2 to str1Length){
            for(i <- 0 to str1Length-len){
                for(j <- 0 to str1Length-len){
                    breakable{
                        for(k <- 1 to len-1){
                            if(dp(i)(j)(k) && dp(i+k)(j+k)(len-k)){
                                dp(i)(j)(len) = true
                                break()
                            }
                            if(dp(i)(j+len-k)(k) && dp(i+k)(j)(len-k)){
                                dp(i)(j)(len) = true
                                break()
                            }  
                        }
                    }
                }
            }
        }
        return dp(0)(0)(str1Length)
    }
}