Minimum Window Substring - Java Solution

1. Introduction

This blog post delves into a common problem in string manipulation: finding the smallest substring in a string s that contains all the characters of another string t, including duplicates. This problem is a classic example of the sliding window technique.

Problem

Given two strings s and t, find the smallest substring of s that has all the characters of t. If no such substring exists, return an empty string.

2. Solution Steps

1. Use a sliding window approach to go through s.

2. Keep track of the characters of t in a frequency map.

3. Expand the window until it contains all characters of t.

4. Once all characters are included, try to shrink the window from the left.

5. Keep track of the minimum length substring that satisfies the condition.

6. Return the smallest substring found, or an empty string if no such substring exists.

3. Code Program

import java.util.HashMap;

public class Solution {

    // Main method for testing
    public static void main(String[] args) {
        System.out.println("Minimum window substring: " + minWindow("ADOBECODEBANC", "ABC"));
        System.out.println("Minimum window substring: " + minWindow("a", "a"));
        System.out.println("Minimum window substring: " + minWindow("a", "aa"));
    }

    // Method to find the minimum window substring
    public static String minWindow(String s, String t) {
        if (t.length() > s.length()) return "";

        HashMap<Character, Integer> tMap = new HashMap<>();
        for (char c : t.toCharArray()) {
            tMap.put(c, tMap.getOrDefault(c, 0) + 1);
        }

        int required = tMap.size();
        int formed = 0;
        int left = 0, right = 0;
        int minLength = Integer.MAX_VALUE, minLeft = 0;

        HashMap<Character, Integer> windowCounts = new HashMap<>();

        while (right < s.length()) {
            char c = s.charAt(right);
            windowCounts.put(c, windowCounts.getOrDefault(c, 0) + 1);

            if (tMap.containsKey(c) && windowCounts.get(c).intValue() == tMap.get(c).intValue()) {
                formed++;
            }

            // Try to contract the window till the point where it ceases to be 'desirable'
            while (left <= right && formed == required) {
                c = s.charAt(left);

                // Save the smallest window until now
                if (right - left + 1 < minLength) {
                    minLength = right - left + 1;
                    minLeft = left;
                }

                windowCounts.put(c, windowCounts.get(c) - 1);
                if (tMap.containsKey(c) && windowCounts.get(c) < tMap.get(c)) {
                    formed--;
                }

                left++;
            }

            right++;
        }

        return minLength == Integer.MAX_VALUE ? "" : s.substring(minLeft, minLeft + minLength);
    }
}

Output:

Minimum window substring: BANC
Minimum window substring: a
Minimum window substring:

Explanation:

The minWindow method applies the sliding window technique to find the smallest substring of s that contains all the characters of t

For the input s = "ADOBECODEBANC" and t = "ABC", it identifies "BANC" as the smallest such substring. In the case of s = "a" and t = "a", the whole string "a" is the answer. 

For s = "a" and t = "aa", no such substring exists, so it returns an empty string.

Comments