From 9826b84b31fced6e4e78bf272a781b2547eb949d Mon Sep 17 00:00:00 2001 From: jaimin45-art Date: Fri, 17 Oct 2025 14:04:49 +0530 Subject: [PATCH 1/2] Added MinimumWindowSubstring.java implementing sliding window approach --- .../strings/MinimumWindowSubstring.java | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 src/main/java/com/thealgorithms/strings/MinimumWindowSubstring.java diff --git a/src/main/java/com/thealgorithms/strings/MinimumWindowSubstring.java b/src/main/java/com/thealgorithms/strings/MinimumWindowSubstring.java new file mode 100644 index 000000000000..9999a1e60a20 --- /dev/null +++ b/src/main/java/com/thealgorithms/strings/MinimumWindowSubstring.java @@ -0,0 +1,80 @@ +package com.thealgorithms.strings; + +import java.util.Arrays; + +/** + * Minimum Window Substring + * + * Given two strings s and t, return the minimum window substring of s such that + * every character in t (including duplicates) is included in the window. + * + * If there is no such substring, return an empty string "". + * + * Approach: sliding window + frequency table. + * + * Time complexity: O(n + m) where n = s.length(), m = t.length() + * Space complexity: O(1) if using fixed-size arrays for ASCII (256). + */ +public final class MinimumWindowSubstring { + + private MinimumWindowSubstring() { + throw new UnsupportedOperationException("Utility class"); + } + + /** + * Returns the minimum window substring of s that contains all chars from t. + * + * @param s source string + * @param t target string + * @return shortest substring of s containing all chars of t, or "" if none + */ + public static String minWindow(String s, String t) { + if (s == null || t == null || s.length() < t.length() || t.length() == 0) { + return ""; + } + + int[] need = new int[256]; + for (char c : t.toCharArray()) { + need[c]++; + } + + int required = 0; + for (int i = 0; i < 256; i++) { + if (need[i] > 0) required++; + } + + int l = 0, r = 0; + int formed = 0; + int[] window = new int[256]; + int minLen = Integer.MAX_VALUE; + int minLeft = 0; + + while (r < s.length()) { + char c = s.charAt(r); + window[c]++; + if (need[c] > 0 && window[c] == need[c]) { + formed++; + } + + // Try and contract the window till the point it ceases to be 'desirable'. + while (l <= r && formed == required) { + // Update result + if (r - l + 1 < minLen) { + minLen = r - l + 1; + minLeft = l; + } + + char d = s.charAt(l); + window[d]--; + if (need[d] > 0 && window[d] < need[d]) { + formed--; + } + l++; + } + + r++; + } + + return minLen == Integer.MAX_VALUE ? "" : s.substring(minLeft, minLeft + minLen); + } +} From 8845666006baa1cf9de6d53d00c31177e62d2b4d Mon Sep 17 00:00:00 2001 From: jaimin45-art Date: Fri, 17 Oct 2025 14:15:27 +0530 Subject: [PATCH 2/2] Added test for MinimumWindowSubstring --- .../strings/MinimumWindowSubstringTest.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/test/java/com/thealgorithms/strings/MinimumWindowSubstringTest.java diff --git a/src/test/java/com/thealgorithms/strings/MinimumWindowSubstringTest.java b/src/test/java/com/thealgorithms/strings/MinimumWindowSubstringTest.java new file mode 100644 index 000000000000..6ab95177f6f1 --- /dev/null +++ b/src/test/java/com/thealgorithms/strings/MinimumWindowSubstringTest.java @@ -0,0 +1,27 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; + +public class MinimumWindowSubstringTest { + + @Test + public void testExample1() { + assertEquals("BANC", MinimumWindowSubstring.minWindow("ADOBECODEBANC", "ABC")); + } + + @Test + public void testExample2() { + assertEquals("", MinimumWindowSubstring.minWindow("A", "AA")); + } + + @Test + public void testExample3() { + assertEquals("a", MinimumWindowSubstring.minWindow("a", "a")); + } + + @Test + public void testExample4() { + assertEquals("t stri", MinimumWindowSubstring.minWindow("test string", "tist")); + } +}