为有牺牲多壮志,敢教日月换新天。

[Swift]LeetCode87. 扰乱字符串 | Scramble String

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/9935700.html 
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

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

We say that "rgeat" is a scrambled string of "great".

Similarly, if we continue to swap the children of nodes "eat" and "at", it produces a scrambled string "rgtae".

    rgtae
   /    \
  rg    tae
 / \    /  \
r   g  ta  e
       / \
      t   a

We say that "rgtae" is a scrambled string of "great".

Given two strings s1 and s2 of the same length, determine if s2 is a scrambled string of s1.

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 }

 

posted @ 2018-11-09 16:13  为敢技术  阅读(318)  评论(0编辑  收藏  举报