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

[Swift]LeetCode567. 字符串的排列 | Permutation in String

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

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

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

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

Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. In other words, one of the first string's permutations is the substring of the second string.

Example 1:

Input:s1 = "ab" s2 = "eidbaooo"
Output:True
Explanation: s2 contains one permutation of s1 ("ba"). 

Example 2:

Input:s1= "ab" s2 = "eidboaoo"
Output: False 

Note:

  1. The input strings only contain lower case letters.
  2. The length of both given strings is in range [1, 10,000].

给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。

换句话说,第一个字符串的排列之一是第二个字符串的子串。

示例1:

输入: s1 = "ab" s2 = "eidbaooo"
输出: True
解释: s2 包含 s1 的排列之一 ("ba"). 

示例2:

输入: s1= "ab" s2 = "eidboaoo"
输出: False 

注意:

  1. 输入的字符串只包含小写字母
  2. 两个字符串的长度都在 [1, 10,000] 之间

36ms

 1 class Solution {
 2     func checkInclusion(_ s1: String, _ s2: String) -> Bool {
 3         guard s1.count <= s2.count else {
 4             return false
 5         }
 6         
 7         func allZero(_ counts: [Int]) -> Bool {
 8             for i in 0 ..< 26 {
 9                 if counts[i] != 0 {
10                     return false
11                 }
12             }
13             return true
14         }
15         
16         let chars1 = Array(s1.unicodeScalars)
17         let chars2 = Array(s2.unicodeScalars)
18         let len1 = chars1.count
19         let len2 = chars2.count
20         var counts = [Int](repeatElement(0, count: 26))
21         
22         for i in 0 ..< len1 {
23             counts[Int(chars1[i].value - 97)] += 1
24             counts[Int(chars2[i].value - 97)] -= 1
25         }
26         
27         if allZero(counts) { return true }
28         
29         for i in len1 ..< len2 {
30             counts[Int(chars2[i].value - 97)] -= 1
31             counts[Int(chars2[i - len1].value - 97)] += 1
32             if allZero(counts) { return true }
33         }
34         
35         return false
36     }
37 }

48ms

 1 class Solution {
 2     func checkInclusion(_ s1: String, _ s2: String) -> Bool {
 3         
 4         var s1Array = Array(s1.characters)
 5         var s2Array = Array(s2.characters)
 6         
 7         if s1Array.count > s2Array.count {
 8             return false 
 9         }
10 
11         var array1 = Array(repeating:0,count:26)     
12         
13         var array2 = Array(repeating:0,count:26)
14         
15         for i in 0 ..< s1Array.count {
16             let index1 = Int(s1Array[i].unicodeScalars.first!.value) - 97 
17             let index2 = Int(s2Array[i].unicodeScalars.first!.value) - 97 
18             
19             array1[index1] += 1
20             array2[index2] += 1 
21         }
22         
23         var end = s1Array.count - 1  
24         var start = 0 
25         while end < s2Array.count{
26             
27               if isMatch(array1,array2){
28                   return true
29               }else{
30                   
31                   let index = Int(s2Array[start].unicodeScalars.first!.value) - 97 
32                   array2[index] -= 1 
33                   start += 1 
34                   
35                   end += 1 
36                   if end < s2Array.count {
37                       let index2 = Int(s2Array[end].unicodeScalars.first!.value) - 97 
38                       array2[index2] += 1 
39                   }
40               }
41         }
42         
43         return false 
44         
45     }
46     
47     func isMatch(_ array1:[Int], _ array2:[Int]) -> Bool{
48         for i in 0 ..< array1.count {
49             if array1[i] != array2[i]{
50                 return false 
51             }
52         }
53         return true
54     }
55 }

52ms

 1 class Solution {
 2     func checkInclusion(_ s1: String, _ s2: String) -> Bool {
 3         var s1 = Array(s1)
 4         var s2 = Array(s2)
 5         let len1 = s1.count
 6         let len2 = s2.count
 7         if len1 > len2 { return false }
 8         let base = Character("a").asciiValue
 9         var count = Array(repeating: 0, count: 26)
10         
11         for i in 0..<len1 {
12             count[s1[i].asciiValue - base] += 1
13             count[s2[i].asciiValue - base] -= 1
14         }
15         
16         if isAllZero(count) { return true }
17         
18         for i in len1..<len2 {
19             count[s2[i].asciiValue - base] -= 1
20             count[s2[i-len1].asciiValue - base] += 1
21             if isAllZero(count) { return true }
22         }
23         return false
24     }
25     
26     func isAllZero(_ arr: [Int]) -> Bool {
27         for num in arr {
28             if num != 0 { return false }
29         }
30         return true
31     }
32 }
33 
34 extension Character {
35     var asciiValue: Int {
36         get {
37             let s = String(self).unicodeScalars
38             return Int(s[s.startIndex].value)
39         }
40     }
41 }

Runtime: 56 ms
Memory Usage: 19.2 MB
 1 class Solution {
 2     func checkInclusion(_ s1: String, _ s2: String) -> Bool {
 3         var arr1:[Character] = Array(s1)
 4         var arr2:[Character] = Array(s2)
 5         var n1:Int = s1.count
 6         var n2:Int = s2.count
 7         var cnt:Int = n1
 8         var left:Int = 0
 9         var m:[Int] = [Int](repeating:0,count:128)
10         for c in arr1
11         {
12             m[c.ascii] += 1
13         }
14         for right in 0..<n2
15         {            
16             if m[arr2[right].ascii] > 0
17             {
18                 cnt -= 1
19             }
20             m[arr2[right].ascii] -= 1
21             while(cnt == 0)
22             {
23                 if right - left + 1 == n1 
24                 {
25                     return true
26                 }
27                  m[arr2[left].ascii] += 1
28                 if m[arr2[left].ascii] > 0
29                 {
30                     cnt += 1
31                 }
32                 left += 1
33             }            
34         }
35         return false
36     }
37 }
38 
39 extension Character  
40 {  
41   //属性:ASCII整数值(定义小写为整数值)
42    var ascii: Int {
43         get {
44             let s = String(self).unicodeScalars
45             return Int(s[s.startIndex].value)
46         }
47     }
48 }

72ms

 1 class Solution {
 2     func checkInclusion(_ s1: String, _ s2: String) -> Bool {
 3         
 4         // if s1 permutation is in s2
 5         
 6         let string1 = Array(s1)
 7         let string2 = Array(s2)
 8         
 9         let originalCharacterToCount = string1.reduce(into: [:], { $0[$1, default: 0] += 1 })
10         
11         var currentCharacterToCount: [Character:Int] = [:]
12         var startIndex = 0
13         
14         for endIndex in 0..<string2.count {
15             
16             let character = string2[endIndex]
17             
18             guard let originalCount = originalCharacterToCount[character] else {
19                 // if this character doesn't exist, then we have to start searching for a new one
20                 currentCharacterToCount = [:]
21                 startIndex = endIndex+1
22                 continue
23             }
24             
25             currentCharacterToCount[character, default: 0] += 1
26             
27             while let currentCount = currentCharacterToCount[character], currentCount > originalCount {
28                 // we can't have TOO many characters - it must match the substring
29                 //
30                 // the guard statment already ensures that we have the RIGHT characters
31                 //
32                 // now we have to worry about the COUNT of the characters
33                 let startCharacter = string2[startIndex]
34                 currentCharacterToCount[startCharacter, default: 0] -= 1
35                 startIndex += 1
36             }
37             
38             if (endIndex - startIndex + 1) == string1.count {
39                 return true
40             }
41         }
42         
43         return false
44     }
45 }

76ms

 1 class Solution {
 2 
 3     func checkInclusion(_ s1: String, _ s2: String) -> Bool {
 4         
 5         let string1Count = s1.count
 6         let string2 = Array(s2)
 7         
 8         let originalCharacterToCount = s1.reduce(
 9             into: [:], 
10             { $0[$1, default: 0] += 1 })
11         
12         var startIndex = 0
13         var currentCharacterToCount: [Character:Int] = [:]
14         
15         for endIndex in 0..<string2.count {
16             let character = string2[endIndex]
17             
18             guard let originalCount = originalCharacterToCount[character] else {
19                 // reset
20                 startIndex = endIndex+1
21                 currentCharacterToCount = [:]
22                 continue
23             }
24             
25             // count
26             currentCharacterToCount[character, default: 0] += 1
27             
28             // adjust startIndex in case we over-counted
29             while let currentCount = currentCharacterToCount[character], currentCount > originalCount {
30                 let startCharacter = string2[startIndex]
31                 startIndex += 1
32                 currentCharacterToCount[startCharacter, default: 1] -= 1
33             }
34             
35             // we don't need character count, we can just use startIndex - endIndex
36             if (endIndex-startIndex+1) == string1Count {
37                 return true
38             }
39         }
40         
41         return false
42     }
43 }

80ms

 1 class Solution {
 2     func checkInclusion(_ s1: String, _ s2: String) -> Bool {
 3         if s1.characters.count > s2.characters.count {
 4             return false
 5         }
 6         
 7         let chars1 = Array(s1.characters)
 8         let chars2 = Array(s2.characters)
 9         let len1 = chars1.count
10         let len2 = chars2.count
11         var counts = [Int](repeatElement(0, count: 256))
12         
13         for i in 0..<len1 {
14             counts[Int((chars1[i].unicodeScalars.first?.value)!)] += 1
15             counts[Int((chars2[i].unicodeScalars.first?.value)!)] -= 1
16         }
17         if allZero(counts) {
18             return true
19         }
20         for i in len1..<len2 {
21             counts[Int((chars2[i].unicodeScalars.first?.value)!)] -= 1
22             counts[Int((chars2[i - len1].unicodeScalars.first?.value)!)] += 1
23             if allZero(counts) {
24                 return true
25             }
26         }
27         
28         return false
29     }
30     
31     private func allZero(_ counts: [Int]) -> Bool {
32         for i in 0..<256 {
33             if counts[i] != 0 {
34                 return false
35             }
36         }
37         return true
38     }    
39 }

84ms

  1 class Solution {
  2     func checkInclusion(_ s1: String, _ s2: String) -> Bool {
  3         let s1Lower = LowerCaseString(s1)
  4         let s2Lower = LowerCaseString(s2)
  5 
  6         let s1Counts = LowerCaseCounter(from: s1Lower).counts
  7         guard let s2Counter = LowerCaseCounter(from: s2Lower,
  8                                                using: s1Lower.data.count) else {
  9             return false
 10         }
 11         
 12         if s1Counts == s2Counter.counts { return true }
 13         
 14         while let s2Counts = s2Counter.step() {
 15             if s1Counts == s2Counts { return true }
 16         }
 17 
 18         return false
 19     }
 20 }
 21 
 22 func unicode(_ c: Character) -> Int {
 23      return Int(c.unicodeScalars.first!.value)
 24 }
 25 
 26 enum LowerCase: Int {
 27     case a = 97
 28     case b
 29     case c
 30     case d
 31     case e
 32     case f
 33     case g
 34     case h
 35     case i
 36     case j
 37     case k
 38     case l
 39     case m
 40     case n
 41     case o
 42     case p
 43     case q
 44     case r
 45     case s
 46     case t
 47     case u
 48     case v
 49     case w
 50     case x
 51     case y
 52     case z
 53 }
 54 
 55 struct LowerCaseString {
 56     private(set) var data: [LowerCase]
 57     
 58     init(_ s: String) {
 59         data = []
 60         data.reserveCapacity(s.count)
 61         for c in s {
 62             let u = unicode(c)
 63             guard let e = LowerCase(rawValue: u) else { continue }
 64             data.append(e)
 65         }
 66     }
 67 }
 68 
 69 
 70 class LowerCaseCounter {
 71     private static var len = 1 + LowerCase.z.rawValue - LowerCase.a.rawValue
 72     private(set) var counts: [Int] = Array(repeating: 0, count: Int(len))
 73     
 74     private var start: IndexingIterator<[LowerCase]>
 75     private var end: IndexingIterator<[LowerCase]>
 76     
 77     init(from s: LowerCaseString) {
 78         start = s.data.makeIterator()
 79         end = s.data.makeIterator()
 80         while let on = end.next() {
 81             let i = on.rawValue - LowerCase.a.rawValue
 82             counts[i] = counts[i] + 1
 83         }
 84     }
 85     
 86     init?(from s: LowerCaseString, using n: Int) {
 87         start = s.data.makeIterator()
 88         end = s.data.makeIterator()
 89         for _ in 0..<n {
 90             guard let on = end.next() else { return nil }
 91             let i = on.rawValue - LowerCase.a.rawValue
 92             counts[i] = counts[i] + 1
 93         }
 94     }
 95     
 96     func step() -> [Int]? {
 97         guard let on = end.next() else { return nil }
 98         guard let off = start.next() else { return nil }
 99         
100         let i = on.rawValue - LowerCase.a.rawValue
101         let j = off.rawValue - LowerCase.a.rawValue
102         
103         counts[i] = counts[i] + 1
104         counts[j] = max(counts[j] - 1, 0)
105 
106         return counts
107     }
108 }

92ms

 1 class Solution {
 2     func checkInclusion(_ s1: String, _ s2: String) -> Bool {
 3         
 4         let a1 = Array(s1).map { String($0) }
 5         let len = a1.count
 6         let a2 = Array(s2).map { String($0) }
 7         if a2.count < len { return false }
 8         var hashA = [String:Int]()
 9         for s in a1 {
10             if let old = hashA[s] {
11                 hashA[s] = old+1
12             } else {
13                 hashA[s] = 1
14             }
15         }
16         
17         
18         var hashB = [String:Int]()
19         
20         var i = 0
21         while i<len{
22             let s = a2[i]
23             if let old = hashB[s] {
24                 hashB[s] = old+1
25             } else {
26                 hashB[s] = 1
27             }
28             i+=1
29         }
30         var runnerHashB = hashB
31         
32         if runnerHashB == hashA {
33             return true
34         }
35         var j = 0
36         
37         while j < (a2.count - len) {
38             
39             if let old = runnerHashB[a2[j]] {
40                 if old == 1 {
41                     runnerHashB[a2[j]] = nil
42                 } else {
43                     runnerHashB[a2[j]] = old - 1
44                 }
45                 
46             }
47             
48             if let old1 = runnerHashB[a2[j+len]] {
49                 runnerHashB[a2[j+len]] = old1 + 1
50             } else {
51                 runnerHashB[a2[j+len]] = 1
52             }
53             if runnerHashB == hashA {
54                 return true
55             }
56             j+=1
57         }
58         return false
59     }
60 }

100ms

 1 class Solution {
 2     func checkInclusion(_ s1: String, _ s2: String) -> Bool {
 3         
 4         if s1.count > s2.count { return false }
 5         
 6         var dict1 = [Character: Int]()
 7         var dict2 = dict1
 8         s1.forEach {
 9             dict1[$0] = (dict1[$0] ?? 0) + 1
10         }
11         
12         
13         let s2 = Array(s2)
14         let n = s1.count
15         for i in 0..<s2.count {
16             dict2[s2[i]] = (dict2[s2[i]] ?? 0) + 1
17             if i >= n {
18                 let count = dict2[s2[i - n]]!
19                 dict2[s2[i - n]] = count == 1 ? nil : count - 1
20             }
21             if dict2 == dict1 {
22                 return true
23             }
24         }
25         
26         return false
27     }
28 }

104ms

 1 class Solution {
 2     func checkInclusion(_ s1: String, _ s2: String) -> Bool {
 3         guard !s1.isEmpty && !s2.isEmpty && s2.count >= s1.count else {
 4             return false
 5         }
 6         
 7         var map: [Character: Int] = [:]
 8         for char in s1 {
 9             if let count = map[char] {
10                 map[char] = count + 1
11             } else {
12                 map[char] = 1
13             }
14         }
15         
16         let chars = Array(s2)
17         var temp = map
18         var left = 0
19         for (index, char) in chars.enumerated() {
20             if let count = temp[char] {
21                 if count > 0 {
22                     let newCount = count - 1
23                     temp[char] = newCount
24                     if newCount == 0 {
25                         let empty = temp.contains { $0.value > 0 }
26                         if !empty {
27                             return true
28                         }
29                     }
30                 } else {
31                     if chars[left] == char {
32                         left += 1
33                     } else {
34                         var index2 = left
35                         while true {
36                             let char2 = chars[index2]
37                             if char2 != char {
38                                 temp[char2] = temp[char2]! + 1
39                             } else {
40                                 left = index2 + 1
41                                 break
42                             }
43                             index2 += 1
44                         }
45                     }
46                 }
47             } else {
48                 temp = map
49                 left = index + 1
50             }
51         }
52         
53         return false
54     }
55 }

148ms

 1 class Solution {
 2     func checkInclusion(_ s1: String, _ s2: String) -> Bool {
 3         
 4         if s1 == "" {
 5             return true
 6         }
 7 
 8         var hash = [Character: Int]()
 9         
10         for ch in s1 {
11             hash[ch] = hash[ch, default: 0] - 1
12         }
13         
14         var count = hash.count 
15        
16         var frt = 0
17         var chArr = Array(s2)
18         for (i, ch) in s2.enumerated() {
19             hash[ch] = hash[ch, default: 0] + 1
20             if hash[ch] == 0 {
21                 hash[ch] = nil
22                 count -= 1
23             }
24             
25             if count == 0 {
26                 while frt < i {
27                     var f = chArr[frt]
28                     if let val = hash[f] {
29                         hash[f] = hash[f]! - 1
30                         if hash[f] == 0 {
31                             hash[f] = nil
32                         }
33                         frt += 1
34                     } else {
35                         break
36                     }
37                 }
38             }
39             
40             if hash.count == 0 {
41                 return true
42             }
43         }
44         return false    
45     }
46 }

232ms

 1 class Solution {
 2     func checkInclusion(_ s1: String, _ s2: String) -> Bool {
 3         let len1 = s1.count 
 4         let len2 = s2.count
 5         
 6         guard len1 <= len2 else { return false }
 7         
 8         var countDict = [Character: Int]()
 9         
10         var s1 = Array(s1)
11         var s2 = Array(s2)
12         
13         for i in 0..<len1 {
14             if let value = countDict[s1[i]] {
15                 countDict[s1[i]] = value + 1
16             } else {
17                 countDict[s1[i]] = 1
18             }
19             
20             if let value = countDict[s2[i]] {
21                 countDict[s2[i]] = value - 1
22             } else {
23                 countDict[s2[i]] = -1
24             }
25         }
26         
27         if allZeroes(countDict.map { $0.value }) { return true }
28         
29         for i in len1..<len2 {
30             if let value = countDict[s2[i]] {
31                 countDict[s2[i]] = value - 1
32             } else {
33                 countDict[s2[i]] = -1
34             }
35             
36             if let value = countDict[s2[i - len1]] {
37                 countDict[s2[i - len1]] = value + 1
38             } else {
39                 countDict[s2[i - len1]] = 1
40             }
41             
42             if allZeroes(countDict.map { $0.value }) { return true }
43         }
44         
45         return false
46     }
47     
48     func allZeroes(_ nums: [Int]) -> Bool {
49         for num in nums {
50             if num != 0 {
51                 return false
52             }
53         }
54         
55         return true
56     }
57 }

 

 

posted @ 2019-02-22 21:01  为敢技术  阅读(532)  评论(0编辑  收藏  举报