/
Hard_076_Minimum_Window_Substring.swift
93 lines (81 loc) · 2.78 KB
/
Hard_076_Minimum_Window_Substring.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
https://leetcode.com/problems/minimum-window-substring/
#76 Minimum Window Substring
Level: hard
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).
For example,
S = "ADOBECODEBANC"
T = "ABC"
Minimum window is "BANC".
Note:
If there is no such window in S that covers all characters in T, return the emtpy string "".
If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.
Inspired by @heleifz at https://leetcode.com/discuss/10337/accepted-o-n-solution
*/
import Foundation
private extension String {
subscript (index: Int) -> Character {
return self[self.index(self.startIndex, offsetBy: index)]
}
}
struct Hard_076_Minimum_Window_Substring {
static func minWindow(s: String, t: String) -> String {
if s.isEmpty || t.isEmpty {
return ""
}
var count = t.count
var charCountDict: Dictionary<Character, Int> = Dictionary()
var charFlagDict: Dictionary<Character, Bool> = Dictionary()
for ii in 0 ..< count {
if let charCount = charCountDict[t[ii]] {
charCountDict[t[ii]] = charCount + 1
} else {
charCountDict[t[ii]] = 1
}
charFlagDict[t[ii]] = true
}
var i = -1
var j = 0
var minLen = Int.max
var minIdx = 0
while i < s.count && j < s.count {
if count > 0 {
i += 1
if i == s.count {
continue
}
if let charCount = charCountDict[s[i]] {
charCountDict[s[i]] = charCount - 1
} else {
charCountDict[s[i]] = -1
}
if let tmpBool = charFlagDict[s[i]] {
if tmpBool == true && charCountDict[s[i]]! >= 0 {
count -= 1
}
}
} else {
if minLen > i - j + 1 {
minLen = i - j + 1
minIdx = j
}
if let charCount = charCountDict[s[j]] {
charCountDict[s[j]] = charCount + 1
} else {
charCountDict[s[j]] = 1
}
if let tmpBool = charFlagDict[s[j]] {
if tmpBool == true && charCountDict[s[j]]! > 0 {
count += 1
}
}
j += 1
}
}
if minLen == Int.max {
return ""
}
let range = s.index(s.startIndex, offsetBy: minIdx) ..< s.index(s.startIndex, offsetBy: minIdx + minLen)
return String(s[range])
}
}