Smallest window that contains all characters of string itself

Given a string, find the smallest window length with all distinct characters of the given string. For eg. str = “aabcbcdbca”, then the result would be 4 as of the smallest window will be “dbca” .

Examples:

Input  : aabcbcdbca
Output : dbca
Explanation : 
dbca of length 4 is the smallest 
window with highest number of distinct
characters.         

Input : aaab
Output : ab
Explanation : 
ab of length 2 is the smallest window 
with highest number of distinct characters.    

Above problem states that we have to find the smallest window that contains all the distinct characters of the given string even if the smallest string contains repeating elements.



For example, in “aabcbcdb”, the smallest string that contains all the characters is “abcbcd”.
This problem reduces to Find the smallest window in a string containing all characters of another string.

In that problem we find the smallest window that contains all the characters of given pattern.

1- Count all distinct characters in given string.

2- Now follow the algorithm discussed in below post.
https://www.geeksforgeeks.org/find-the-smallest-window-in-a-string-containing-all-characters-of-another-string/
We basically maintain a window of characters. Whenever the window contains all characters of given string, we shrink the window from left side to remove extra characters and then compare its length with smallest window fount so far.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find the smallest window containing
// all characters of a pattern.
#include<bits/stdc++.h>
using namespace std;
  
const int MAX_CHARS = 256;
  
// Function to find smallest window containing
// all distinct characters
string findSubString(string str)
{
    int n = str.length();
  
    // Count all distinct characters.
    int dist_count = 0;
    bool visited[MAX_CHARS] = {false};
    for (int i=0; i<n; i++)
    {
        if (visited[str[i]] == false)
        {
            visited[str[i]] = true;
            dist_count++;
        }
    }
  
    // Now follow the algorithm discussed in below
    // post. We basically maintain a window of characters
    // that contains all characters of given string.
    int start = 0, start_index = -1, min_len = INT_MAX;
  
    int count = 0;
    int curr_count[MAX_CHARS] = {0};
    for (int j=0; j<n; j++)
    {
        // Count occurrence of characters of string
        curr_count[str[j]]++;
  
        // If any distinct character matched,
        // then increment count
        if (curr_count[str[j]] == 1 )
            count++;
  
        // if all the characters are matched
        if (count == dist_count)
        {
            // Try to minimize the window i.e., check if
            // any character is occurring more no. of times
            // than its occurrence in pattern, if yes
            // then remove it from starting and also remove
            // the useless characters.
            while (curr_count[str[start]] > 1)
            {
                if (curr_count[str[start]] > 1)
                    curr_count[str[start]]--;
                start++;
            }
  
            // Update window size
            int len_window = j - start + 1;
            if (min_len > len_window)
            {
                min_len = len_window;
                start_index = start;
            }
        }
    }
  
    // Return substring starting from start_index
    // and length min_len
    return str.substr(start_index, min_len);
}
  
// Driver code
int main()
{
    string str = "aabcbcdbca";
    cout << "Smallest window containing all distinct"
            " characters is " << findSubString(str);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find the smallest window containing
// all characters of a pattern.
import java.util.Arrays;
public class GFG {
  
    static final int MAX_CHARS = 256;
       
    // Function to find smallest window containing
    // all distinct characters
    static String findSubString(String str)
    {
        int n = str.length();
       
        // Count all distinct characters.
        int dist_count = 0;
          
        boolean[] visited = new boolean[MAX_CHARS];
        Arrays.fill(visited, false);
        for (int i=0; i<n; i++)
        {
            if (visited[str.charAt(i)] == false)
            {
                visited[str.charAt(i)] = true;
                dist_count++;
            }
        }
       
        // Now follow the algorithm discussed in below
        // post. We basically maintain a window of characters
        // that contains all characters of given string.
        int start = 0, start_index = -1;
        int min_len = Integer.MAX_VALUE;
       
        int count = 0;
        int[] curr_count =  new int[MAX_CHARS];
        for (int j=0; j<n; j++)
        {
            // Count occurrence of characters of string
            curr_count[str.charAt(j)]++;
       
            // If any distinct character matched,
            // then increment count
            if (curr_count[str.charAt(j)] == 1 )
                count++;
       
            // if all the characters are matched
            if (count == dist_count)
            {
                // Try to minimize the window i.e., check if
                // any character is occurring more no. of times
                // than its occurrence in pattern, if yes
                // then remove it from starting and also remove
                // the useless characters.
                while (curr_count[str.charAt(start)] > 1)
                {
                    if (curr_count[str.charAt(start)] > 1)
                        curr_count[str.charAt(start)]--;
                    start++;
                }
                  
                // Update window size
                int len_window = j - start + 1;
                if (min_len > len_window)
                {
                    min_len = len_window;
                    start_index = start;
                }
            }
        }
        // Return substring starting from start_index
        // and length min_len
        return str.substring(start_index, start_index+min_len);
    }
       
    // Driver code
    public static void main(String args[])
    {
        String str = "aabcbcdbca";
        System.out.println("Smallest window containing all distinct"
               + " characters is " + findSubString(str));
    }
}
// This code is contributed by Sumit Ghosh

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to find the smallest 
# window containing
# all characters of a pattern
  
from collections import defaultdict
  
MAX_CHARS = 256
  
# Function to find smallest window 
# containing
# all distinct characters
  
  
def findSubString(str):
    n = len(str)
      
    # Count all distinct characters.
    dist_count = len(set([x for x in str]))
  
    # Now follow the algorithm discussed in below
    # post. We basically maintain a window of characters
    # that contains all characters of given string.
  
    count, start, start_index, min_len = 0, 0, -1, 9999999999
    curr_count = defaultdict(lambda: 0)
    for j in range(n):
        curr_count[str[j]] += 1
        # If any distinct character matched,
        # then increment count
  
        if curr_count[str[j]] == 1:
            count += 1
  
        # Try to minimize the window i.e., check if
        # any character is occurring more no. of times
        # than its occurrence in pattern, if yes
        # then remove it from starting and also remove
        # the useless characters.
  
        if count == dist_count:
            while curr_count[str[start]] > 1:
                if curr_count[str[start]] > 1:
                    curr_count[str[start]] -= 1
                start += 1
  
            # Update window size
            len_window = j - start + 1
            if min_len > len_window:
                min_len = len_window
                start_index = start
  
    # Return substring starting from start_index
    # and length min_len """
    return str[start_index: start_index + min_len]
      
# Driver code
if __name__=='__main__':
    print("Smallest window containing all distinct characters is {}"
         .format(findSubString("aabcbcdbca")))
  
# This code is contributed by 
# Subhrajit

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to find the smallest window containing
// all characters of a pattern.
using System;
  
class GFG 
      
static int MAX_CHARS = 256;
  
// Function to find smallest window containing
// all distinct characters
static string findSubString(string str)
{
    int n = str.Length;
  
    // Count all distinct characters.
    int dist_count = 0;
    bool []visited = new bool[MAX_CHARS];
    for (int i = 0; i < n; i++)
    {
        if (visited[str[i]] == false)
        {
            visited[str[i]] = true;
            dist_count++;
        }
    }
  
    // Now follow the algorithm discussed in below
    // post. We basically maintain a window of characters
    // that contains all characters of given string.
    int start = 0, start_index = -1, min_len = int.MaxValue;
  
    int count = 0;
    int []curr_count = new int[MAX_CHARS];
    for (int j = 0; j < n; j++)
    {
        // Count occurrence of characters of string
        curr_count[str[j]]++;
  
        // If any distinct character matched,
        // then increment count
        if (curr_count[str[j]] == 1 )
            count++;
  
        // if all the characters are matched
        if (count == dist_count)
        {
            // Try to minimize the window i.e., check if
            // any character is occurring more no. of times
            // than its occurrence in pattern, if yes
            // then remove it from starting and also remove
            // the useless characters.
            while (curr_count[str[start]] > 1)
            {
                if (curr_count[str[start]] > 1)
                    curr_count[str[start]]--;
                start++;
            }
  
            // Update window size
            int len_window = j - start + 1;
            if (min_len > len_window)
            {
                min_len = len_window;
                start_index = start;
            }
        }
    }
  
    // Return substring starting from start_index
    // and length min_len
    return str.Substring(start_index, min_len);
}
  
// Driver code
public static void Main(String[] args) 
    string str = "aabcbcdbca";
    Console.WriteLine("Smallest window containing all distinct"
        + " characters is " + findSubString(str));
  
// This code contributed by Rajput-Ji

chevron_right



Output:

Smallest window containing all distinct characters is dbca

Related Article :
Length of the smallest sub-string consisting of maximum distinct characters

This article is contributed by Sahil Chhabra. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.



My Personal Notes arrow_drop_up