Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.thealgorithms.strings;

/**
* 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)
* Space complexity: O(1) for ASCII characters.
*
* Reference: https://en.wikipedia.org/wiki/Minimum_window_substring
*/
public final class MinimumWindowSubstring {

private MinimumWindowSubstring() {
throw new UnsupportedOperationException("Utility class");
}

public static String minWindow(String s, String t) {
if (s == null || t == null || s.length() < t.length() || t.isEmpty()) {
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, formed = 0;
int[] window = new int[256];
int minLen = Integer.MAX_VALUE, minLeft = 0;

while (r < s.length()) {
char c = s.charAt(r);
window[c]++;
if (need[c] > 0 && window[c] == need[c]) formed++;

while (l <= r && formed == required) {
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);
}
}
Original file line number Diff line number Diff line change
@@ -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"));
}
}
Loading