Given strings s1 and s2, return _the minimum contiguous substring part of _s1, so thats2is a subsequence of the part.
If there is no such window in s1 that covers all characters in s2, return the empty string "". If there are multiple such minimum-length windows, return the one with the left-most starting index.
Input: s1 ="abcdebdde", s2 ="bde"Output: "bcde"Explanation:
"bcde"is the answer because it occurs before "bdde" which has the same length."deb"is not a smaller window because the elements of s2 in the window must occur in order.
To find the minimum window in s1 containing s2 as a subsequence, we scan s1 to find the end of a valid window, then backtrack to find its start. By repeating this process, we can find the smallest such window efficiently.
classSolution {
public: string minWindow(string s1, string s2) {
int m = s1.size(), n = s2.size();
int min_len = INT_MAX, start =-1;
for (int i =0; i < m; ++i) {
if (s1[i] != s2[0]) continue;
int j = i, k =0;
while (j < m && k < n) {
if (s1[j] == s2[k]) ++k;
++j;
}
if (k == n) {
int end = j -1;
k = n -1;
j = end;
while (j >= i) {
if (s1[j] == s2[k]) {
if (--k <0) break;
}
--j;
}
if (end - j < min_len) {
min_len = end - j;
start = j +1;
}
}
}
return start ==-1?"": s1.substr(start, min_len);
}
};
classSolution {
public String minWindow(String s1, String s2) {
int m = s1.length(), n = s2.length();
int minLen = Integer.MAX_VALUE, start =-1;
for (int i = 0; i < m; i++) {
if (s1.charAt(i) != s2.charAt(0)) continue;
int j = i, k = 0;
while (j < m && k < n) {
if (s1.charAt(j) == s2.charAt(k)) k++;
j++;
}
if (k == n) {
int end = j - 1;
k = n - 1;
j = end;
while (j >= i) {
if (s1.charAt(j) == s2.charAt(k)) {
if (--k < 0) break;
}
j--;
}
if (end - j < minLen) {
minLen = end - j;
start = j + 1;
}
}
}
return start ==-1 ?"" : s1.substring(start, start + minLen);
}
}
classSolution {
funminWindow(s1: String, s2: String): String {
val m = s1.length
val n = s2.length
var minLen = Int.MAX_VALUE
var start = -1for (i in0 until m) {
if (s1[i] != s2[0]) continuevar j = i
var k = 0while (j < m && k < n) {
if (s1[j] == s2[k]) k++ j++ }
if (k == n) {
val end = j - 1 k = n - 1 j = end
while (j >= i) {
if (s1[j] == s2[k]) {
k--if (k < 0) break }
j-- }
if (end - j < minLen) {
minLen = end - j
start = j + 1 }
}
}
returnif (start == -1) ""else s1.substring(start, start + minLen)
}
}
classSolution:
defminWindow(self, s1: str, s2: str) -> str:
m, n = len(s1), len(s2)
min_len, start = float('inf'), -1 i =0while i < m:
if s1[i] == s2[0]:
j, k = i, 0while j < m and k < n:
if s1[j] == s2[k]:
k +=1 j +=1if k == n:
end = j -1 k = n -1 j = end
while j >= i:
if s1[j] == s2[k]:
k -=1if k <0:
break j -=1if end - j < min_len:
min_len = end - j
start = j +1 i +=1return""if start ==-1else s1[start:start+min_len]
impl Solution {
pubfnmin_window(s1: String, s2: String) -> String {
let m = s1.len();
let n = s2.len();
let s1_bytes = s1.as_bytes();
let s2_bytes = s2.as_bytes();
letmut min_len =usize::MAX;
letmut start = None;
for i in0..m {
if s1_bytes[i] != s2_bytes[0] {
continue;
}
let (mut j, mut k) = (i, 0);
while j < m && k < n {
if s1_bytes[j] == s2_bytes[k] {
k +=1;
}
j +=1;
}
if k == n {
let end = j -1;
k = n -1;
j = end;
while j >= i {
if s1_bytes[j] == s2_bytes[k] {
if k ==0 { break; }
k -=1;
}
if j ==0 { break; }
j -=1;
}
if end - j < min_len {
min_len = end - j;
start = Some(j +1);
}
}
}
match start {
Some(idx) => s1[idx..idx+min_len].to_string(),
None => String::new(),
}
}
}