★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:http://www.javashuo.com/article/p-tmohqyly-me.html
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html
Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrings recursively.node
Below is one possible representation of s1 = "great"
:git
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.github
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"
.spa
Similarly, if we continue to swap the children of nodes "eat"
and "at"
, it produces a scrambled string "rgtae"
.code
rgtae / \ rg tae / \ / \ r g ta e / \ t a
We say that "rgtae"
is a scrambled string of "great"
.htm
Given two strings s1 and s2 of the same length, determine if s2 is a scrambled string of s1.blog
Example 1:遞歸
Input: s1 = "great", s2 = "rgeat" Output: true
Example 2:
Input: s1 = "abcde", s2 = "caebd" Output: false
給定一個字符串 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
56ms
1 class Solution { 2 func isScramble(_ s1: String, _ s2: String) -> Bool { 3 if s1 == s2 { 4 return true 5 } 6 7 var letters = [Int](repeating: 0, count: 26) 8 9 for i in 0..<s1.count { 10 let aASCII = Character("a").ascii 11 letters[s1[i].ascii - aASCII] += 1 12 letters[s2[i].ascii - aASCII] -= 1 13 } 14 for i in 0..<26 { 15 if letters[i] != 0 { 16 return false 17 } 18 } 19 for i in 1..<s1.count { 20 if isScramble(s1[0..<i], s2[0..<i]) && 21 isScramble(s1[i..<s1.count], s2[i..<s2.count]) { 22 return true 23 } 24 if isScramble(s1[0..<i], s2[(s2.count - i)..<s2.count]) && 25 isScramble(s1[i..<s1.count], s2[0..<(s2.count - i)]) { 26 return true 27 } 28 } 29 30 return false 31 } 32 } 33 34 extension String { 35 subscript (i: Int) -> Character { 36 return self[index(startIndex, offsetBy: i)] 37 } 38 39 subscript(_ range: CountableRange<Int>) -> String { 40 let idx1 = index(startIndex, offsetBy: max(0, range.lowerBound)) 41 let idx2 = index(startIndex, offsetBy: min(self.count, range.upperBound)) 42 return String(self[idx1..<idx2]) 43 } 44 } 45 46 extension Character { 47 var ascii: Int { 48 get { 49 let s = String(self).unicodeScalars 50 return Int(s[s.startIndex].value) 51 } 52 } 53 54 func isDigit() -> Bool { 55 return self >= "0" && self <= "9" 56 } 57 }
56ms
1 class Solution { 2 func isScramble(_ s1: String, _ s2: String) -> Bool { 3 return isScramble_recursion(s1: s1, s2: s2) 4 } 5 6 func isScramble_recursion(s1: String?, s2: String?) -> Bool { 7 if s1 == nil || s2 == nil || s1?.count != s2?.count { 8 return false 9 } 10 if s1 == s2 { 11 return true 12 } 13 if (s1?.sorted())! != (s2?.sorted())! { 14 return false 15 } 16 let count: Int = (s1?.count)! 17 for i in 1 ..< count { 18 if isScramble_recursion(s1: s1![0..<i], s2: s2![0..<i]) && isScramble_recursion(s1: s1![i..<Int.max], s2: s2![i..<Int.max]) { 19 return true 20 } 21 if isScramble_recursion(s1: s1![0..<i], s2: s2![(s2?.count)! - i..<Int.max]) && isScramble_recursion(s1: s1![i..<Int.max], s2: s2![0..<(s2?.count)! - i]) { 22 return true 23 } 24 } 25 return false 26 } 27 static func isScramble_iteration(s1: String?, s2: String?) -> Bool { 28 if s1 == nil || s2 == nil || s1?.count != s2?.count { 29 return false 30 } 31 let len = s1?.count 32 var dp: Array<Array<Array<Bool>>> = Array<Array<Array<Bool>>>(repeating: Array<Array<Bool>>(repeating: Array<Bool>(repeating: false, count: 100), count: 100), count: 100) 33 for i in (0...len! - 1).reversed() { 34 for j in (0...len!-1).reversed() { 35 dp[i][j][1] = (s1![i] == s2![j]) 36 var l = 2 37 while i + l <= len! && j + l <= len! { 38 for n in 1 ..< l { 39 dp[i][j][l] = dp[i][j][l] || ( dp[i][j][n] && dp[i+n][j+n][l-n] ) 40 dp[i][j][l] = dp[i][j][l] || ( dp[i][j+l-n][n] && dp[i+n][j][l-n] ) 41 } 42 l += 1 43 } 44 } 45 } 46 return dp[0][0][len!] 47 } 48 } 49 private extension String { 50 subscript (range: Range<Int>) -> String { 51 guard let localEndIndex = self.index(self.startIndex, offsetBy: range.upperBound, limitedBy: self.endIndex) else { 52 return String(self[self.index(self.startIndex, offsetBy: range.lowerBound)..<self.endIndex]) 53 } 54 return String(self[self.index(self.startIndex, offsetBy: range.lowerBound)..<localEndIndex]) 55 } 56 subscript (index: Int) -> Character { 57 return self[self.index(self.startIndex, offsetBy: index)] 58 } 59 }
180ms
1 class Solution { 2 3 func isScramble(_ s1: String, _ s2: String) -> Bool { 4 guard s1.count == s2.count else { return false } 5 guard s1.count > 0 else { return false } 6 7 var dp = [[[Bool]]](repeating: [[Bool]](repeating: [Bool](repeating: false, count: s1.count + 1), count: s1.count), count: s1.count) 8 9 for i in 0..<s1.count { 10 for j in 0..<s2.count { 11 dp[i][j][1] = s1.charAt(i) == s2.charAt(j) 12 } 13 } 14 15 if s1.count > 1 { 16 for len in 2...s1.count { 17 for i in 0...s1.count - len { 18 for j in 0...s2.count - len { 19 for w in 1..<len { 20 if dp[i][j][w] && dp[i + w][j + w][len - w] { 21 dp[i][j][len] = true 22 break 23 } 24 if dp[i][j + len - w][w] && dp[i + w][j][len - w] { 25 dp[i][j][len] = true 26 break 27 } 28 } 29 } 30 } 31 } 32 } 33 34 return dp[0][0][s1.count] 35 } 36 } 37 38 extension String { 39 40 func charAt(_ i: Int) -> Character { 41 let index = self.index(self.startIndex, offsetBy: i) 42 return self[index] 43 } 44 }