Minimum Window Substring (Length)
Problem
Two words are given: s and t. Find the shortest continuous part of s that contains every letter of t (a letter that appears twice in t must appear at least twice in the part). Print its length, or 0 if there is no such part.
Constraints
- 1 <= length <= 10^4
- ASCII letters
Examples
Input
ADOBECODEBANC ABC
Output
4
Solutions
The window grows on the right until it has every needed letter. Then it shrinks from the left while it stays valid, and the shortest size is remembered. Each position enters and leaves once: O(n).
/*
* Problem : Shortest window.
* Input : Words s and t.
* Output : The length.
* Approach: Sliding window
* Time : O(n + m)
* Space : O(1)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// This method solves the task. It receives the input and returns the answer.
static int solve(String a, String b) {
// Step 1: need[c] is how many letters c are still missing in the window.
int[] need = new int[128];
for (int i = 0; i < b.length(); i++) {
need[b.charAt(i)]++;
}
int missing = b.length();
int left = 0;
int best = 0;
for (int right = 0; right < a.length(); right++) {
// Step 2: Add a letter on the right. It reduces "missing" only if the window still needed it.
if (need[a.charAt(right)]-- > 0) {
missing--;
}
// Step 3: The window is valid when nothing is missing. Shrink it from the left as far as possible.
while (missing == 0) {
int size = right - left + 1;
if (best == 0 || size < best) {
best = size;
}
if (++need[a.charAt(left++)] > 0) {
missing++;
}
}
}
return best;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String a = scanner.next();
String b = scanner.next();
System.out.println(solve(a, b));
}
}
Hints (2)
- When is the window valid?
- Why does need go below zero?