Bird
Raised Fist0
DSA Typescriptprogramming~5 mins

Minimum Window Substring in DSA Typescript - Time & Space Complexity

Choose your learning style10 modes available
Time Complexity: Minimum Window Substring
O(n + m)
Understanding Time Complexity

We want to understand how the time needed to find the smallest substring containing all characters from another string changes as input size grows.

How does the algorithm's work increase when the strings get longer?

Scenario Under Consideration

Analyze the time complexity of the following code snippet.


function minWindow(s: string, t: string): string {
  const need = new Map();
  for (const c of t) need.set(c, (need.get(c) || 0) + 1);
  let left = 0, right = 0, count = t.length;
  let minLen = Infinity, start = 0;
  while (right < s.length) {
    if (need.has(s[right])) {
      if (need.get(s[right])! > 0) count--;
      need.set(s[right], need.get(s[right])! - 1);
    }
    right++;
    while (count === 0) {
      if (right - left < minLen) {
        minLen = right - left;
        start = left;
      }
      if (need.has(s[left])) {
        need.set(s[left], need.get(s[left])! + 1);
        if (need.get(s[left])! > 0) count++;
      }
      left++;
    }
  }
  return minLen === Infinity ? "" : s.substring(start, start + minLen);
}
    

This code finds the smallest substring in s that contains all characters from t using a sliding window approach.

Identify Repeating Operations

Identify the loops, recursion, array traversals that repeat.

  • Primary operation: The outer while loop moves the right pointer through string s.
  • Secondary operation: The inner while loop moves the left pointer to shrink the window when all needed characters are found.
  • How many times: Each character in s is visited at most twice, once by right and once by left.
How Execution Grows With Input

As the input string s grows, the pointers move through it linearly.

Input Size (n = length of s)Approx. Operations
10About 20 pointer moves (each character visited twice)
100About 200 pointer moves
1000About 2000 pointer moves

Pattern observation: The number of operations grows roughly twice the input size, which is still linear growth.

Final Time Complexity

Time Complexity: O(n + m)

This means the time grows linearly with the size of both strings s and t.

Common Mistake

[X] Wrong: "Because there are nested loops, the time complexity must be quadratic (O(n²))."

[OK] Correct: The inner loop doesn't run fully for each outer loop step; both pointers only move forward through s once, so total work is linear.

Interview Connect

Understanding this sliding window approach and its linear time complexity shows you can handle efficient substring problems, a common skill interviewers look for.

Self-Check

"What if we used a nested loop that restarted the left pointer from zero each time? How would the time complexity change?"

Practice

(1/5)
1. What is the main goal of the Minimum Window Substring problem?
easy
A. Sort characters of a string in ascending order
B. Find the smallest substring in a string that contains all characters of another string
C. Count the number of substrings containing a specific character
D. Find the longest substring without repeating characters

Solution

  1. Step 1: Understand the problem statement

    The problem asks to find the smallest part of a string that has all characters from another string.
  2. Step 2: Identify the goal

    The goal is to find the minimum length substring that contains all required characters, not just any substring.
  3. Final Answer:

    Find the smallest substring in a string that contains all characters of another string -> Option B
  4. Quick Check:

    Minimum window substring = smallest substring with all chars [OK]
Hint: Look for smallest substring covering all target chars [OK]
Common Mistakes:
  • Confusing with longest substring problems
  • Ignoring the requirement to include all characters
  • Thinking it's about sorting characters
2. Which of the following TypeScript code snippets correctly initializes a frequency map for characters in string t for the Minimum Window Substring problem?
easy
A. const freqMap = {}; for (let i = 0; i < t.length; i++) { freqMap[t[i]] = freqMap[t[i]] + 1; }
B. const freqMap = new Map(); for (const ch of t) { freqMap[ch] = freqMap[ch] + 1; }
C. const freqMap = new Map(); for (const ch of t) { freqMap.set(ch, (freqMap.get(ch) ?? 0) + 1); }
D. const freqMap = new Map(); for (const ch of t) { freqMap.set(ch, freqMap.get(ch) + 1); }

Solution

  1. Step 1: Check correct Map usage in TypeScript

    const freqMap = new Map(); for (const ch of t) { freqMap.set(ch, (freqMap.get(ch) ?? 0) + 1); } uses Map with get and set methods and handles undefined with nullish coalescing (?? 0).
  2. Step 2: Identify errors in other options

    const freqMap = {}; for (let i = 0; i < t.length; i++) { freqMap[t[i]] = freqMap[t[i]] + 1; } uses object but does not initialize counts, causing NaN. const freqMap = new Map(); for (const ch of t) { freqMap[ch] = freqMap[ch] + 1; } uses Map but accesses like object property, which is incorrect. const freqMap = new Map(); for (const ch of t) { freqMap.set(ch, freqMap.get(ch) + 1); } does not handle undefined before adding 1, causing NaN.
  3. Final Answer:

    const freqMap = new Map(); for (const ch of t) { freqMap.set(ch, (freqMap.get(ch) ?? 0) + 1); } -> Option C
  4. Quick Check:

    Use Map.get with ?? 0 to avoid undefined [OK]
Hint: Use Map.get with ?? 0 to safely increment counts [OK]
Common Mistakes:
  • Accessing Map like an object property
  • Not initializing counts before increment
  • Using object without initializing keys
3. What will be the output of the following TypeScript code snippet for s = "ADOBECODEBANC" and t = "ABC"?
function minWindow(s: string, t: string): string {
  const freqMap = new Map();
  for (const ch of t) freqMap.set(ch, (freqMap.get(ch) ?? 0) + 1);
  let left = 0, right = 0, count = t.length, minLen = Infinity, start = 0;
  while (right < s.length) {
    const ch = s[right];
    if (freqMap.has(ch)) {
      freqMap.set(ch, freqMap.get(ch)! - 1);
      if (freqMap.get(ch)! >= 0) count--;
    }
    while (count === 0) {
      if (right - left + 1 < minLen) {
        minLen = right - left + 1;
        start = left;
      }
      const leftChar = s[left];
      if (freqMap.has(leftChar)) {
        freqMap.set(leftChar, freqMap.get(leftChar)! + 1);
        if (freqMap.get(leftChar)! > 0) count++;
      }
      left++;
    }
    right++;
  }
  return minLen === Infinity ? "" : s.substring(start, start + minLen);
}
console.log(minWindow(s, t));
medium
A. "BANC"
B. "ADOBEC"
C. "CODEBA"
D. "DOBECODEBA"

Solution

  1. Step 1: Understand the sliding window approach

    The code uses two pointers expanding and shrinking the window to find the smallest substring containing all chars of t.
  2. Step 2: Trace the code with given input

    The minimum window substring containing A, B, and C in s = "ADOBECODEBANC" and t = "ABC" is "BANC".
  3. Final Answer:

    "BANC" -> Option A
  4. Quick Check:

    Minimum window substring for "ABC" in "ADOBECODEBANC" is "BANC" [OK]
Hint: Use sliding window to shrink when all chars matched [OK]
Common Mistakes:
  • Returning first found substring instead of minimum
  • Not updating minimum length correctly
  • Incorrectly increasing count when shrinking window
4. Identify the bug in the following TypeScript code snippet for Minimum Window Substring and select the fix:
function minWindow(s: string, t: string): string {
  const freqMap = new Map();
  for (const ch of t) freqMap.set(ch, (freqMap.get(ch) ?? 0) + 1);
  let left = 0, right = 0, count = t.length, minLen = Infinity, start = 0;
  while (right < s.length) {
    const ch = s[right];
    if (freqMap.has(ch)) {
      freqMap.set(ch, freqMap.get(ch)! - 1);
      if (freqMap.get(ch)! > 0) count--;
    }
    while (count === 0) {
      if (right - left + 1 < minLen) {
        minLen = right - left + 1;
        start = left;
      }
      const leftChar = s[left];
      if (freqMap.has(leftChar)) {
        freqMap.set(leftChar, freqMap.get(leftChar)! + 1);
        if (freqMap.get(leftChar)! > 0) count++;
      }
      left++;
    }
    right++;
  }
  return minLen === Infinity ? "" : s.substring(start, start + minLen);
}
medium
A. Change condition from if (freqMap.get(ch)! > 0) count--; to if (freqMap.get(ch)! >= 0) count--;
B. Initialize count with 0 instead of t.length
C. Remove the inner while loop
D. Change freqMap.set(ch, freqMap.get(ch)! - 1); to freqMap.set(ch, freqMap.get(ch)! + 1);

Solution

  1. Step 1: Identify the condition for decreasing count

    The count should decrease when a needed character is found and its frequency is still >= 0, not > 0.
  2. Step 2: Fix the condition

    Changing from > 0 to >= 0 ensures count decreases correctly when the character frequency reaches zero.
  3. Final Answer:

    Change condition from if (freqMap.get(ch)! > 0) count--; to if (freqMap.get(ch)! >= 0) count--; -> Option A
  4. Quick Check:

    Use >= 0 to count chars correctly [OK]
Hint: Use >= 0 when checking frequency to update count [OK]
Common Mistakes:
  • Using > 0 causes missing valid matches
  • Incorrect count initialization
  • Removing inner loop breaks shrinking window
5. Given strings s = "aabbccdd" and t = "abc", which of the following substrings is the correct minimum window substring containing all characters of t? Consider that characters can appear multiple times in s but only once in t.
hard
A. "aabbc"
B. "abc"
C. "bcca"
D. "abbc"

Solution

  1. Step 1: Understand character requirements

    String t requires one 'a', one 'b', and one 'c'. The substring must contain at least these once.
  2. Step 2: Find smallest substring in s containing 'a', 'b', 'c'

    "abbc" contains 'a', 'b', 'b', 'c' and is length 4. "abc" does not appear as a contiguous substring in s. "bcca" and "aabbc" are longer substrings.
  3. Final Answer:

    "abbc" -> Option D
  4. Quick Check:

    Minimum window substring with all chars = "abbc" [OK]
Hint: Check substring length and character coverage carefully [OK]
Common Mistakes:
  • Assuming "abc" substring exists exactly
  • Ignoring repeated characters in s
  • Choosing longer substrings unnecessarily
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard