Open In App

Smallest window that contains all characters of string itself

Last Updated : 23 Jul, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a string str, your task is to find the smallest window length that contains all the characters of the given string at least one time.

Examples: 

Input: str = "aabcbcdbca"
Output: 4
Explanation: Sub-string -> "dbca"

Input: str = "aaab"
Output: 2
Explanation: Sub-string -> "ab"

[Naive Approach] - Generating All Substrings - O(n ^ 2) Time and O(1) Space

The idea is to first identify all the unique characters using a count array. Then, by generating all possible substrings and checking whether each contains all the unique characters, we can track and update the shortest valid substring found. The approach involves efficiently tracking which characters have been seen using a visited array and leveraging two pointers to examine different substrings. Once a substring contains all distinct characters, we compare its length with the minimum length found so far and update the result if necessary.

C++
#include <bits/stdc++.h>
using namespace std;

int findSubString(string &str) {
    int n = str.size();

    int ans = n;

    // to store all distinct characters
    vector<bool> visited(26, false);
    for (int i = 0; i < n; i++) {
        visited[str[i]-'a'] = true;
    }

    for(int i = 0; i < n; i++) {
        vector<bool> cur(26, false);

        for(int j = i; j < n; j++) {
            cur[str[j]-'a'] = true;

            // if all characters are present
            if(cur == visited) {
                ans = min(ans, j - i + 1);
                break;
            }
        }
    }

    return ans;
}

int main() {
    string str = "aabcbcdbca";
    cout << findSubString(str);
    return 0;
}
Java
import java.util.Arrays;

class GfG {

    public static int findSubString(String str) {
        int n = str.length();

        int ans = n;

        // to store all distinct characters
        boolean[] visited = new boolean[26];
        for (int i = 0; i < n; i++) {
            visited[str.charAt(i) - 'a'] = true;
        }

        for (int i = 0; i < n; i++) {
            boolean[] cur = new boolean[26];

            for (int j = i; j < n; j++) {
                cur[str.charAt(j) - 'a'] = true;

                // if all characters are present
                if (Arrays.equals(cur, visited)) {
                    ans = Math.min(ans, j - i + 1);
                    break;
                }
            }
        }

        return ans;
    }

    public static void main(String[] args) {
        String str = "aabcbcdbca";
        System.out.print(findSubString(str));
    }
}
Python
def findSubString(str):
    n = len(str)

    ans = n

    # to store all distinct characters
    visited = [False] * 26
    for i in range(n):
        visited[ord(str[i]) - ord('a')] = True

    for i in range(n):
        cur = [False] * 26

        for j in range(i, n):
            cur[ord(str[j]) - ord('a')] = True

            # if all characters are present
            if cur == visited:
                ans = min(ans, j - i + 1)
                break

    return ans

if __name__ == "__main__":
    str = "aabcbcdbca"
    print(findSubString(str))
C#
using System;
using System.Linq;

class GfG {

    public static int findSubString(string str) {
        int n = str.Length;

        int ans = n;

        // to store all distinct characters
        bool[] visited = new bool[26];
        for (int i = 0; i < n; i++) {
            visited[str[i] - 'a'] = true;
        }

        for (int i = 0; i < n; i++) {
            bool[] cur = new bool[26];

            for (int j = i; j < n; j++) {
                cur[str[j] - 'a'] = true;

                // if all characters are present
                if (cur.SequenceEqual(visited)) {
                    ans = Math.Min(ans, j - i + 1);
                    break;
                }
            }
        }

        return ans;
    }

    static void Main() {
        string str = "aabcbcdbca";
        Console.Write(findSubString(str));
    }
}
JavaScript
function findSubString(str) {
    let n = str.length;

    let ans = n;

    // to store all distinct characters
    let visited = new Array(26).fill(false);
    for (let i = 0; i < n; i++) {
        visited[str.charCodeAt(i) - 97] = true;
    }

    for (let i = 0; i < n; i++) {
        let cur = new Array(26).fill(false);

        for (let j = i; j < n; j++) {
            cur[str.charCodeAt(j) - 97] = true;

            // if all characters are present
            if (JSON.stringify(cur) === JSON.stringify(visited)) {
                ans = Math.min(ans, j - i + 1);
                break;
            }
        }
    }

    return ans;
}

let str = "aabcbcdbca";
console.log(findSubString(str));

Output
4

[Expected Approach] - Using Sliding Window - O(n) Time and O(1) Space

The idea is to maintain a sliding window over the string using two pointers, expanding the window until it contains all distinct characters, then contracting it from the left to remove any redundant characters while still covering all distinct characters. By continuously updating the minimum window size seen whenever the window is valid, we achieve a linear-time solution.

Follow the below given steps:

  • Use an array visited[26] to mark all distinct characters in the input string, tracking the total in distinct.
  • Initialize a second array cur[26] to count character frequencies within the current window, and a counter cnt to track how many distinct characters the window currently contains.
  • Set start = 0 and iterate i from 0 to n–1:
    • Increment cur[str[i] - 'a'], if this becomes 1, increment cnt.
    • While cnt == distinct, update ans = min(ans, i – start + 1), then decrement cur[str[start] - 'a'], if it becomes 0, decrement cnt, and increment start to shrink the window.
  • Return ans as the length of the smallest substring containing all distinct characters.


Smallest-window-that-contains-all-characters-of-string-itself


C++
#include <bits/stdc++.h>
using namespace std;

int findSubString(string str) {
    int n = str.size();

    // to store all distinct characters
    vector<bool> visited(26, false);
    int distinct = 0;

    for (int i = 0; i < n; i++) {
        if (visited[str[i] - 'a'] == false) {
            visited[str[i] - 'a'] = true;
            distinct++;
        }
    }

    // to store the visited of characters
    // in the current window
    vector<int> cur(26, 0);
    int cnt = 0;

    int ans = n;
    int start = 0;
    for(int i = 0; i < n; i++) {
        
        // Count characters in the current
        // window
        cur[str[i] - 'a']++;
        if(cur[str[i] - 'a'] == 1) {
            cnt++;
        }
        
        // If the count becomes same as overall
        while(cnt == distinct) {
            ans = min(ans, i - start + 1);
            
            // Remove characters from left
            cur[str[start] - 'a']--;
            if(cur[str[start] - 'a'] == 0) {
                cnt--;
            }
            start++;
        }
    }
    return ans;
}

int main() {
    string str = "aabcbcdbca";
    cout << findSubString(str);
    return 0;
}
Java
import java.util.Arrays;

class GfG {

    public static int findSubString(String str) {
        int n = str.length();


        // to store all distinct characters
        boolean[] visited = new boolean[26];
        int distinct = 0;

        for (int i = 0; i < n; i++) {
            if (visited[str.charAt(i) - 'a'] == false) {
                visited[str.charAt(i) - 'a'] = true;
                distinct++;
            }
        }


        // to store the visited of characters
        // in the current window
        int[] cur = new int[26];
        int cnt = 0;

        int ans = n;
        int start = 0;
        for (int i = 0; i < n; i++) {
            cur[str.charAt(i) - 'a']++;

            if (cur[str.charAt(i) - 'a'] == 1) {
                cnt++;
            }
            while (cnt == distinct) {
                ans = Math.min(ans, i - start + 1);
                cur[str.charAt(start) - 'a']--;
                if (cur[str.charAt(start) - 'a'] == 0) {
                    cnt--;
                }
                start++;
            }
        }
        return ans;
    }

    public static void main(String[] args) {
        String str = "aabcbcdbca";
        System.out.print(findSubString(str));
    }
}
Python
def findSubString(str):
    n = len(str)


    # to store all distinct characters
    visited = [False] * 26
    distinct = 0

    for i in range(n):
        if visited[ord(str[i]) - ord('a')] == False:
            visited[ord(str[i]) - ord('a')] = True
            distinct += 1


    # to store the visited of characters

    # in the current window
    cur = [0] * 26
    cnt = 0

    ans = n
    start = 0
    for i in range(n):
        cur[ord(str[i]) - ord('a')] += 1

        if cur[ord(str[i]) - ord('a')] == 1:
            cnt += 1
        while cnt == distinct:
            ans = min(ans, i - start + 1)
            cur[ord(str[start]) - ord('a')] -= 1
            if cur[ord(str[start]) - ord('a')] == 0:
                cnt -= 1
            start += 1
    return ans

if __name__ == "__main__":
    str = "aabcbcdbca"
    print(findSubString(str))
C#
using System;

class GfG {

    public static int findSubString(string str) {
        int n = str.Length;
        
        // to store all distinct characters
        bool[] visited = new bool[26];
        int distinct = 0;

        for (int i = 0; i < n; i++) {
            if (visited[str[i] - 'a'] == false) {
                visited[str[i] - 'a'] = true;
                distinct++;
            }
        }

        // to store the visited of characters
        // in the current window
        int[] cur = new int[26];
        int cnt = 0;

        int ans = n;
        int start = 0;
        for (int i = 0; i < n; i++) {
            cur[str[i] - 'a']++;

            if (cur[str[i] - 'a'] == 1) {
                cnt++;
            }
            while (cnt == distinct) {
                ans = Math.Min(ans, i - start + 1);
                cur[str[start] - 'a']--;
                if (cur[str[start] - 'a'] == 0) {
                    cnt--;
                }
                start++;
            }
        }
        return ans;
    }

    static void Main() {
        string str = "aabcbcdbca";
        Console.Write(findSubString(str));
    }
}
JavaScript
function findSubString(str) {
    let n = str.length;


    // to store all distinct characters
    let visited = new Array(26).fill(false);
    let distinct = 0;

    for (let i = 0; i < n; i++) {
        if (visited[str.charCodeAt(i) - 97] == false) {
            visited[str.charCodeAt(i) - 97] = true;
            distinct++;
        }
    }
    
    // to store the visited of characters
    // in the current window
    let cur = new Array(26).fill(0);
    let cnt = 0;

    let ans = n;
    let start = 0;
    for (let i = 0; i < n; i++) {
        cur[str.charCodeAt(i) - 97]++;

        if (cur[str.charCodeAt(i) - 97] == 1) {
            cnt++;
        }
        while (cnt == distinct) {
            ans = Math.min(ans, i - start + 1);
            cur[str.charCodeAt(start) - 97]--;
            if (cur[str.charCodeAt(start) - 97] == 0) {
                cnt--;
            }
            start++;
        }
    }
    return ans;
}

// driver code 
let str = "aabcbcdbca";
console.log(findSubString(str));

Output
4

Related Article: 


Similar Reads