zoukankan      html  css  js  c++  java
  • [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 }

     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 }

     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 }

     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 }

     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 }
  • 相关阅读:
    VS2015调试ArcMap Add-in插件提示尝试运行项目时出错,无法启动程序“路径arcmap.exe”
    c#重命名文件,报错“System.NotSupportedException”类型的未经处理的异常在 mscorlib.dll 中发生”
    C# string contains 不区分大小写
    CSS div 高度满屏
    ArcGIS Server SOE开发之奇怪异常:
    C# 读取XML注释
    .Net程序员之不学Java做安卓开发:奇怪的Java语法
    .Net程序员之不学Java做安卓开发:Android Studio中的即时调试窗口
    JS去遍历Table的所有单元格中的内容
    判断 checkbox 是否选中以及 设置checkbox选中
  • 原文地址:https://www.cnblogs.com/strengthen/p/9931643.html
Copyright © 2011-2022 走看看