[Swift]LeetCode76. 最小覆盖子串 | Minimum Window Substring
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/9931643.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).
Example:
Input: S = "ADOBECODEBANC", T = "ABC" Output: "BANC"
Note:
- If there is no such window in S that covers all characters in T, return the empty string
""
. - If there is such window, you are guaranteed that there will always be only one unique minimum window in S.
给定一个字符串 S 和一个字符串 T,请在 S 中找出包含 T 所有字母的最小子串。
示例:
输入: S = "ADOBECODEBANC", T = "ABC" 输出: "BANC"
说明:
- 如果 S 中不存这样的子串,则返回空字符串
""
。 - 如果 S 中存在这样的子串,我们保证它是唯一的答案。
40ms
1 class Solution { 2 //initialize two pointers- left and right and initialize both to the first element of string s. 3 //In any sliding window problem, we have two pointers. One right pointer whose job is to expand the current 4 //window and the left pointer whose hob is to contract the given window. At any point, only one of those pointers 5 //move and the other stay fixed. 6 7 func minWindow(_ s: String, _ t: String) -> String { 8 //convert the strings to character array 9 //the map is necessary to convert uint8 to Int 10 let schars = Array(s.utf8).map {Int($0)} 11 let tchars = Array(t.utf8).map {Int($0)} 12 13 14 //create hashmap 15 var hash = Array(repeating: 0, count: 128) 16 17 for tchar in tchars { 18 hash[tchar] += 1 19 } 20 21 var count = tchars.count 22 var start = 0 23 var left = 0 24 var right = 0 25 var length = Int.max 26 27 //We use the right pointer to expand the window until we get a desirable window i.e. a window that contains all of the characters of 28 // t 29 while right < schars.count { 30 //if this character from schars is present in hash (i.e. in tchars), decrement count and also the count for that char in the hash by 1. 31 if hash[schars[right]] > 0 { 32 count -= 1 33 } 34 hash[schars[right]] -= 1 35 right += 1 36 37 while count == 0 { 38 if right - left < length { 39 //keep updating the length value 40 length = right - left 41 start = left 42 } 43 //Once we have a window with all the characters, we can move the left pointer ahead one by one. If the window is still a desirable one we keep //updating the minimum window size. 44 if hash[schars[left]] == 0 { 45 count += 1 46 } 47 hash[schars[left]] += 1 48 left += 1 49 } 50 } 51 52 //not present 53 if length > schars.count { 54 return "" 55 } 56 57 let index1 = s.index(s.startIndex, offsetBy: start) 58 let index2 = s.index(s.startIndex, offsetBy: start + length) 59 60 return String(s[index1..<index2]) 61 } 62 }
44ms
1 class Solution { 2 func minWindow(_ s: String, _ t: String) -> String { 3 4 let tt = Array(t.utf16).map { Int($0) } 5 let ss = Array(s.utf16).map { Int($0) } 6 // create hashmap 7 var hash = [Int](repeating: 0, count: 128) 8 for n in tt { 9 hash[n] += 1 10 } 11 12 var count = tt.count, start = 0, l = 0, r = 0, length = Int.max 13 14 while r < ss.count { 15 if hash[ss[r]] > 0 { 16 count -= 1 17 } 18 hash[ss[r]] -= 1 19 r += 1 20 while count == 0 { 21 if r - l < length { 22 length = r - l 23 start = l 24 } 25 if hash[ss[l]] == 0 { 26 count += 1 27 } 28 hash[ss[l]] += 1 29 l += 1 30 } 31 } 32 33 if length > ss.count { 34 return "" 35 } 36 37 let index1 = s.index(s.startIndex, offsetBy: start) 38 let index2 = s.index(s.startIndex, offsetBy: start + length) 39 return s.substring(with: index1..<index2) 40 } 41 }
48ms
1 class Solution { 2 func minWindow(_ s: String, _ t: String) -> String { 3 let ss = Array(s.utf8).map(Int.init) 4 let tt = Array(t.utf8).map(Int.init) 5 var counts = [Int](repeating: 0, count: 256) 6 for char in tt { 7 counts[char] += 1 8 } 9 var left = 0 10 var size = t.count 11 var res = (-1, -1) 12 var minL = Int.max 13 for right in 0..<s.count { 14 counts[ss[right]] -= 1 15 if counts[ss[right]] >= 0 { 16 size -= 1 17 } 18 19 if size == 0 { 20 inner: while left < right { 21 counts[ss[left]] += 1 22 if counts[ss[left]] > 0 { 23 size += 1 24 break inner 25 } 26 left += 1 27 } 28 if right - left + 1 < minL { 29 minL = right - left + 1 30 res = (left, right) 31 } 32 left += 1 33 } 34 } 35 if res == (-1, -1) { return "" } 36 let arr = ss[res.0...res.1] 37 return String(arr.map { Character(UnicodeScalar($0)!) } ) 38 } 39 }
Runtime: 52 ms
Memory Usage: 20.3 MB
1 class Solution { 2 func minWindow(_ s: String, _ t: String) -> String { 3 var counter:Int = 0 4 var minlen:Int = Int.max 5 var begin:Int = 0 6 var end:Int = 0 7 var head:Int = 0 8 var m:[Int] = [Int](repeating:0,count:128) 9 counter = t.count 10 var arrT:[Int] = Array(t).map{$0.ascii} 11 for c in arrT 12 { 13 m[c]++ 14 } 15 var arrS:[Int] = Array(s).map{$0.ascii} 16 while(end < arrS.count) 17 { 18 if m[arrS[end++]]-- > 0 19 { 20 counter-- 21 } 22 while(counter==0) 23 { 24 if minlen > end - begin 25 { 26 head = begin 27 minlen = end - (head) 28 } 29 if m[arrS[begin++]]++ == 0 30 { 31 counter++ 32 } 33 } 34 } 35 let str:String = (minlen == Int.max) ? "" :s.subString(head,minlen) 36 return str 37 38 } 39 } 40 41 /*扩展Int类,实现自增++、自减--运算符*/ 42 extension Int{ 43 //后缀++:先执行表达式后再自增 44 static postfix func ++(num:inout Int) -> Int { 45 //输入输出参数num 46 let temp = num 47 //num加1 48 num += 1 49 //返回加1前的数值 50 return temp 51 } 52 //后缀--:先执行表达式后再自减 53 static postfix func --(num:inout Int) -> Int { 54 //输入输出参数num 55 let temp = num 56 //num减1 57 num -= 1 58 //返回减1前的数值 59 return temp 60 } 61 } 62 63 64 //Character扩展方法 65 extension Character 66 { 67 //属性:ASCII整数值(定义小写为整数值) 68 var ascii: Int { 69 get { 70 let s = String(self).unicodeScalars 71 return Int(s[s.startIndex].value) 72 } 73 } 74 } 75 76 extension String { 77 78 // 截取字符串:指定索引和字符数 79 // - begin: 开始截取处索引 80 // - count: 截取的字符数量 81 func subString(_ begin:Int,_ count:Int) -> String { 82 let start = self.index(self.startIndex, offsetBy: max(0, begin)) 83 let end = self.index(self.startIndex, offsetBy: min(self.count, begin + count)) 84 return String(self[start..<end]) 85 } 86 }
52ms
1 class Solution { 2 func minWindow(_ s: String, _ t: String) -> String { 3 var chs = Array(s) 4 let s = s.map { letterIndex($0) } 5 let t = t.map { letterIndex($0) } 6 var map = [Int](repeating:0, count:256) 7 for ch in t { 8 map[ch] += 1 9 } 10 var minLen = Int.max, count = t.count 11 var j = 0, startIndex = 0 12 for i in 0..<s.count { 13 while j < s.count && count > 0 { 14 if map[s[j]] > 0 { 15 count -= 1 16 } 17 map[s[j]] -= 1 18 j += 1 19 } 20 if count == 0 && j - i < minLen{ 21 minLen = j - i 22 startIndex = i 23 } 24 if map[s[i]] >= 0 { 25 count += 1 26 } 27 map[s[i]] += 1 28 } 29 return minLen == Int.max ? "" : String(chs[startIndex..<(startIndex+minLen)]) 30 } 31 32 func letterIndex(_ letter: Character) -> Int { 33 return Int(letter.unicodeScalars.first!.value) 34 } 35 }
72ms
1 class Solution { 2 func minWindow(_ s: String, _ t: String) -> String { 3 var map = [Character : Int]() //t's char and count 4 var diff = t.count 5 var left = 0 6 var right = 0 7 // var res = "" 8 var len = Int.max 9 var start = 0 10 let sArr = Array(s) 11 for char in t { 12 map[char, default: 0 ] += 1 // count 13 } 14 15 while right < sArr.count { 16 let char = sArr[right] 17 18 if let count = map[char] { //t has this char 19 if count > 0 { //this is useful to diff 20 diff -= 1 21 } 22 map[char] = count - 1 23 } 24 if diff == 0 { // found an ans 25 while left <= right{ 26 if let count = map[sArr[left]] { 27 if count == 0 { 28 if right - left + 1 < len{ 29 len = right - left + 1 30 start = left 31 } 32 map[sArr[left]] = count + 1 33 left += 1 34 diff += 1 35 break 36 } 37 map[sArr[left]] = count + 1 38 } 39 left += 1 40 } 41 } 42 43 right += 1 44 } 45 if len == Int.max { return "" } 46 // print(start) 47 // print(len) 48 return String(sArr[start ..< start + len]) 49 } 50 }
76ms
1 class Solution { 2 func minWindow(_ s: String, _ t: String) -> String { 3 guard s.count>=t.count else {return ""} 4 5 var dic = [String.Element:Int]() 6 let sChars = Array(s) 7 let tChars = Array(t) 8 9 for char in tChars { 10 if let val = dic[char] { 11 dic[char] = val+1 12 } else { 13 dic[char] = 1 14 } 15 } 16 17 var start = 0 18 var minStart = 0, minLength = Int.max 19 var numOfTargets = t.count 20 21 for end in 0..<sChars.count { 22 23 if let curOcurrance = dic[sChars[end]] { 24 if curOcurrance > 0 { 25 numOfTargets -= 1 26 } 27 dic[sChars[end]] = curOcurrance-1 28 } 29 30 while numOfTargets == 0 { 31 if minLength > end-start+1 { 32 minLength = end-start+1 33 minStart = start 34 } 35 36 if let curOccurance = dic[sChars[start]] { 37 if curOccurance == 0 { 38 numOfTargets += 1 39 } 40 dic[sChars[start]] = curOccurance+1 41 } 42 start+=1 43 } 44 } 45 46 return minLength == Int.max ? "" : String(sChars[minStart..<minStart+minLength]) 47 } 48 }
84ms
1 class Solution { 2 func minWindow(_ s: String, _ t: String) -> String { 3 var len = Int.max 4 var count = t.count 5 var result = "" 6 7 var dict: [Character: Int] = [:] 8 for c in t { 9 dict[c, default: 0] += 1 10 } 11 12 var i = 0, start = 0 13 var startIndex = s.startIndex, iIndex = s.startIndex 14 15 while iIndex < s.endIndex { 16 let c = s[iIndex] 17 18 if let cnt = dict[c] { 19 dict[c] = cnt - 1 20 21 if cnt >= 1 { 22 count -= 1 23 } 24 } 25 26 while count == 0 && start <= i { 27 if i - start + 1 < len { 28 len = i - start + 1 29 result = String(s[startIndex...iIndex]) 30 } 31 32 let startChar = s[startIndex] 33 if let cnt = dict[startChar] { 34 dict[startChar] = cnt + 1 35 36 if cnt >= 0 { 37 count += 1 38 } 39 } 40 start += 1 41 startIndex = s.index(after: startIndex) 42 } 43 44 iIndex = s.index(after: iIndex) 45 i += 1 46 } 47 48 return result 49 } 50 }
88ms
1 class Solution { 2 func minWindow(_ s: String, _ t: String) -> String { 3 4 if s == t { 5 return s 6 } 7 var charMap : [Character: Int] = [:] 8 var charMap2 : [Character: Int] = [:] 9 for ch in t { 10 if let val = charMap[ch] { 11 charMap[ch] = val + 1 12 } else { 13 charMap[ch] = 1 14 } 15 charMap2[ch] = 0 16 } 17 let sCount = s.length 18 var sChar = Array(s) 19 var lPtr = 0 20 var rPtr = 0 21 var resultLeft = 0 22 var resultRight = 0 23 let tCount = t.length 24 var currentCount = 0 25 var found = false 26 27 while rPtr < sCount { 28 if let rVal = charMap2[sChar[rPtr]] { 29 charMap2[sChar[rPtr]] = rVal + 1 30 if let val = charMap[sChar[rPtr]], rVal < val { 31 currentCount += 1 32 } 33 } 34 35 if currentCount == tCount { 36 if (resultLeft == 0 && resultRight == 0) || (resultRight - resultLeft > rPtr - lPtr) { 37 resultLeft = lPtr 38 resultRight = rPtr 39 found = true 40 } 41 while lPtr < sCount { 42 if let lVal = charMap2[sChar[lPtr]] { 43 charMap2[sChar[lPtr]] = lVal - 1 44 if let val = charMap[sChar[lPtr]] { 45 if lVal == val { 46 currentCount -= 1 47 if (resultRight - resultLeft > rPtr - lPtr) { 48 resultLeft = lPtr 49 resultRight = rPtr 50 } 51 lPtr += 1 52 break 53 } 54 } 55 } 56 lPtr += 1 57 } 58 } 59 rPtr += 1 60 } 61 62 if found { 63 let indexLeft = s.index(s.startIndex, offsetBy: resultLeft) 64 let indexRight = s.index(s.startIndex, offsetBy: resultRight) 65 return String(s[indexLeft...indexRight]) 66 } 67 68 return "" 69 } 70 }
20024 kb
1 class Solution { 2 func minWindow(_ s: String, _ t: String) -> String { 3 guard !s.isEmpty && !t.isEmpty else { 4 return "" 5 } 6 7 var wordLetters = [Character: Int]() 8 9 for symb in t { 10 let count = wordLetters[symb] ?? 0 11 wordLetters[symb] = count + 1 12 } 13 14 var visitedCharacters = [Character: Int]() 15 16 let string = Array(s) 17 18 var left = 0 19 var right = 0 20 21 var bestWindow: ArraySlice<Character>? 22 23 while right < string.count { 24 let letter = string[right] 25 right += 1 26 27 let count = visitedCharacters[letter] ?? 0 28 visitedCharacters[letter] = count + 1 29 30 var validWindow = true 31 32 for (key, count) in wordLetters { 33 let visitedCount = visitedCharacters[key] ?? 0 34 if visitedCount < count { 35 validWindow = false 36 break 37 } 38 } 39 40 while validWindow { 41 if (bestWindow?.count ?? Int.max) > right - left { 42 bestWindow = string[left..<right] 43 } 44 let sCount = visitedCharacters[string[left]] ?? 1 45 visitedCharacters[string[left]] = sCount - 1 46 left += 1 47 48 for (key, count) in wordLetters { 49 let visitedCount = visitedCharacters[key] ?? 0 50 if visitedCount < count { 51 validWindow = false 52 break 53 } 54 } 55 56 } 57 } 58 59 guard let window = bestWindow else { return "" } 60 return String(window) 61 } 62 }
20052 kb
1 class Solution { 2 func minWindow(_ s: String, _ t: String) -> String { 3 var counts = [Character:Int]() 4 for char in t { 5 let count = counts[char, default: 0] 6 counts[char] = count + 1 7 } 8 var counter = counts.count 9 var left = 0 10 var right = 0 11 var result = "" 12 var length = Int.max 13 let s = Array(s) 14 while right < s.count { 15 if let count = counts[s[right]] { 16 counts[s[right]] = count - 1 17 if count - 1 == 0 { 18 counter -= 1 19 } 20 } 21 right += 1 22 while counter == 0 { 23 if right - left < length { 24 length = right - left 25 result = String(s[left..<right]) 26 } 27 if let count = counts[s[left]] { 28 counts[s[left]] = count + 1 29 if count + 1 == 1 { 30 counter += 1 31 } 32 } 33 left += 1 34 } 35 } 36 37 return result 38 } 39 }
20124 kb
1 class Solution { 2 func minWindow(_ s: String, _ t: String) -> String { 3 guard !s.isEmpty && !t.isEmpty else { 4 return "" 5 } 6 7 var wordLetters = [Character: Int]() 8 9 var formed = 0 10 11 for symb in t { 12 let count = wordLetters[symb] ?? 0 13 wordLetters[symb] = count + 1 14 } 15 let required = wordLetters.count 16 17 var visitedCharacters = [Character: Int]() 18 19 let string = Array(s) 20 21 var left = 0 22 var right = 0 23 24 var bL = 0 25 var bR = Int.max 26 27 while right < string.count { 28 let letter = string[right] 29 right += 1 30 31 let count = visitedCharacters[letter] ?? 0 32 visitedCharacters[letter] = count + 1 33 34 if (wordLetters[letter] ?? 0) != 0 && wordLetters[letter] == visitedCharacters[letter] { 35 formed += 1 36 } 37 38 39 while formed == required { 40 if (bR - bL) > right - left { 41 bR = right 42 bL = left 43 } 44 let letter = string[left] 45 let sCount = (visitedCharacters[letter] ?? 1) - 1 46 visitedCharacters[letter] = sCount 47 48 if let wordCount = wordLetters[letter], 49 wordCount > sCount { 50 formed -= 1 51 } 52 left += 1 53 54 } 55 } 56 57 guard bR < Int.max else { return "" } 58 return String(string[bL..<bR]) 59 } 60 }