Smallest window containing 0, 1 and 2

Last Updated : 20 Apr, 2026

Given a string s consisting of the characters 0, 1 and 2, find the length of the smallest substring of string s that contains all the three characters 0, 1 and 2. If no such substring exists, then return -1.

Examples:

Input: s = "01212"
Output: 3
Explanation: The substring 012 is the smallest substring that contains the characters 0, 1 and 2.

Input: s = "12121"
Output: -1
Explanation:  As the character 0 is not present in the string s, therefore no substring containing all the three characters 0, 1 and 2 exists. Hence, the answer is -1 in this case.

Try It Yourself
redirect icon

Using Index Tracking - O(n) Time and O(1) Space

The idea is to keep track of the last seen indices of '0', '1', and '2' while iterating through the string. Once all three characters are found, compute the substring length as the difference between the maximum and minimum of the three indices. Update the minimum length found and print the result.

C++
#include <algorithm>
#include <climits>
#include <iostream>
#include <string>

using namespace std;

int smallestSubstring(string &s)
{
    int res = INT_MAX;

    // To check 0, 1 and 2
    bool zero = false, one = false, two = false;

    // To store indexes of 0, 1 and 2
    int zeroindex, oneindex, twoindex;

    for (int i = 0; i < s.length(); i++)
    {
        if (s[i] == '0')
        {
            zero = true;
            zeroindex = i;
        }
        else if (s[i] == '1')
        {
            one = true;
            oneindex = i;
        }
        else if (s[i] == '2')
        {
            two = true;
            twoindex = i;
        }

        // Calculating length
        if (zero and one and two)
            res = min(res, max({zeroindex, oneindex, twoindex}) - min({zeroindex, oneindex, twoindex}));
    }

    // In case if there is no substring that contains 0,1 and 2
    if (res == INT_MAX)
        return -1;
    return res + 1;
}

int main()
{
    string s = "01212";
    cout << smallestSubstring(s);
    return 0;
}
C
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>

// function to calculate max of two numbers
int min_two(int a, int b)
{
    if (a <= b)
        return a;
    else
        return b;
}

// function to calculate max of three numbers
int max_three(int a, int b, int c)
{
    if (a >= b && a >= c)
        return a;
    else if (b > a && b >= c)
        return b;
    else if (c > a && c > b)
        return c;
}

// function to calculate min of three numbers
int min_three(int a, int b, int c)
{
    if (a <= b && a <= c)
        return a;
    else if (b < a && b <= c)
        return b;
    else if (c < a && c < b)
        return c;
}

// Function to find the length of
// the smallest substring
int smallestSubstring(char s[])
{
    int res = INT_MAX;
    int n = strlen(s);
    // To check 0, 1 and 2
    bool zero = 0, one = 0, two = 0;

    // To store indexes of 0, 1 and 2
    int zeroindex, oneindex, twoindex;
    for (int i = 0; i < n; i++)
    {
        if (s[i] == '0')
        {
            zero = true;
            zeroindex = i;
        }
        else if (s[i] == '1')
        {
            one = true;
            oneindex = i;
        }
        else if (s[i] == '2')
        {
            two = true;
            twoindex = i;
        }

        // Calculating length
        if (zero && one && two)
            res = min_two(res, max_three(zeroindex, oneindex, twoindex) -
                                   min_three(zeroindex, oneindex, twoindex));
    }

    // In case if there is no substring that contains 0,1 and 2
    if (res == INT_MAX)
        return -1;
    return res + 1;
}

int main()
{
    char s[] = "01212";

    int ans = smallestSubstring(s);
    printf("%d", ans);
    return 0;
}
Java
import java.util.*;
class GfG {

    public static int smallestSubstring(String s)
    {
        int res = Integer.MAX_VALUE;

        // To check 0, 1 and 2
        boolean zero = false, one = false, two = false;

        // To store indexes of 0, 1 and 2
        int zeroindex = 0, oneindex = 0, twoindex = 0;
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == '0') {
                zero = true;
                zeroindex = i;
            }
            else if (s.charAt(i) == '1') {
                one = true;
                oneindex = i;
            }
            else if (s.charAt(i) == '2') {
                two = true;
                twoindex = i;
            }

            // Calculating length
            if (zero && one && two)
                res = Math.min(
                    res,
                    Math.max(zeroindex,
                             Math.max(oneindex, twoindex))
                        - Math.min(
                            zeroindex,
                            Math.min(oneindex, twoindex)));
        }

        // In case if there is no substring that contains
        // 0,1 and 2
        if (res == Integer.MAX_VALUE)
            return -1;
        return res + 1;
    }

    public static void main(String[] args)
    {
        String s = "01212";
        System.out.print(smallestSubstring(s));
    }
}
Python
def smallestSubstring(s):
    res = 999999

    # To check 0, 1 and 2
    zero = 0
    one = 0
    two = 0

    # To store indexes of 0, 1 and 2
    zeroindex = 0
    oneindex = 0
    twoindex = 0
    for i in range(len(s)):
        if (s[i] == '0'):
            zero = 1
            zeroindex = i

        elif (s[i] == '1'):
            one = 1
            oneindex = i

        elif (s[i] == '2'):
            two = 1
            twoindex = i

        # Calculating length
        if (zero and one and two):
            res = min(res,
                      max([zeroindex, oneindex, twoindex])
                      - min([zeroindex, oneindex, twoindex]))

    # In case if there is no substring that contains 0,1 and 2
    if (res == 999999):
        return -1
    return res + 1


if __name__ == "__main__":

    s = "01212"
    print(smallestSubstring(s))
C#
using System;

public class GfG {

    static int smallestSubstring(string s)
    {
        int res = Int32.MaxValue;

        // To check 0, 1 and 2
        bool zero = false, one = false, two = false;

        // To store indexes of 0, 1 and 2
        int zeroindex = 0, oneindex = 0, twoindex = 0;
        for (int i = 0; i < s.Length; i++) {
            if (s[i] == '0') {
                zero = true;
                zeroindex = i;
            }
            else if (s[i] == '1') {
                one = true;
                oneindex = i;
            }
            else if (s[i] == '2') {
                two = true;
                twoindex = i;
            }

            // Calculating length
            if (zero && one && two)
                res = Math.Min(
                    res,
                    Math.Max(zeroindex,
                             Math.Max(oneindex, twoindex))
                        - Math.Min(
                            zeroindex,
                            Math.Min(oneindex, twoindex)));
        }

        // In case if there is no substring that contains
        // 0,1 and 2
        if (res == Int32.MaxValue)
            return -1;
        return res + 1;
    }

    static public void Main()
    {
        string s = "01212";
        Console.Write(smallestSubstring(s));
    }
}
JavaScript
function smallestSubstring(s)
{
    let res = 9999999;

    // To check 0, 1 and 2
    let zero = false, one = false, two = false;

    // To store indexes of 0, 1 and 2
    let zeroindex, oneindex, twoindex;
    for (let i = 0; i < s.length; i++) {
        if (s[i] == "0") {
            zero = true;
            zeroindex = i;
        }
        else if (s[i] == "1") {
            one = true;
            oneindex = i;
        }
        else if (s[i] == "2") {
            two = true;
            twoindex = i;
        }

        // Calculating length
        if (zero && one && two)
            res = Math.min(
                res,
                Math.max(...[zeroindex, oneindex, twoindex])
                    - Math.min(...[zeroindex, oneindex,
                                   twoindex]));
    }

    // In case if there is no substring that contains 0,1
    // and 2
    if (res == 9999999)
        return -1;
    return res + 1;
}

// Driver Code
let s = "01212";
console.log(smallestSubstring(s));

Output
3

Using a sliding window - O(n) Time and O(1) Space

The idea is to use two pointers (i and j) and a frequency array to track the count of '0', '1', and '2'. Expand the window by moving j, and when all three characters are present, shrink it from the left (i) to maintain the smallest valid substring. Print the minimum length found.

Dry run for string s = "01212":

  1. Initialize i = 0, j = 0, cnt = 0, min_len = INT_MAX and freq = {0, 0, 0}
  2. For j = 0, add '0': freq = {1, 0, 0}, cnt = 1 and cnt != 3 no update, expand window.
  3. For j = 1, add '1': freq = {1, 1, 0}, cnt = 2 and cnt != 3 no update, expand window.
  4. For j = 2, add '2': freq = {1, 1, 1}, cnt = 3. Now all digits are present hence, update min_len = min(INT_MAX, 2 - 0 + 1) = 3 and remove s[i] = '0': freq = {0, 1, 1}, increment i to 1, cnt = 2
  5. For j = 3, add '1': freq = {0, 2, 1}, cnt = 2 and cnt != 3 no update, expand window.
  6. For j = 4, add '2': freq = {0, 2, 2}, cnt = 2 and cnt != 3 no update, expand window.

So, final answer is min_len = 3.

C++
#include <algorithm>
#include <climits>
#include <iostream>
#include <string>

using namespace std;

int smallestSubstring(string &s)
{
    int n = s.length(), i = 0, j = 0, cnt = 0, min_len = INT_MAX;

    // Stores frequency of digits 0, 1 and 2 inside current window
    int freq[3] = {0};
    while (j < n)
    {
        freq[s[j] - '0']++;
        if (freq[s[j] - '0'] == 1)
            cnt++;

        // When all three digits are present, try to shrink the window
        if (cnt == 3)
        {
            while (freq[s[i] - '0'] > 1)
            {
                freq[s[i] - '0']--;
                i++;
            }

            // Update minimum length of valid substring
            min_len = min(min_len, j - i + 1);
            freq[s[i] - '0']--;
            i++;
            cnt--;
        }

        // Expand window by moving right pointer
        j++;
    }
    return (min_len == INT_MAX) ? -1 : min_len;
}

int main()
{
    string s = "01212";
    cout << smallestSubstring(s) << endl;
    return 0;
}
C
#include <stdio.h>
#include <limits.h>

int smallestSubstring(char *s)
{
    int n = strlen(s), i = 0, j = 0, cnt = 0, min_len = INT_MAX;

    // Stores frequency of digits 0, 1 and 2 inside current window
    int freq[3] = {0};
    while (j < n)
    {
        freq[s[j] - '0']++;
        if (freq[s[j] - '0'] == 1)
            cnt++;

        // When all three digits are present, try to shrink the window
        if (cnt == 3)
        {
            while (freq[s[i] - '0'] > 1)
            {
                freq[s[i] - '0']--;
                i++;
            }

            // Update minimum length of valid substring
            min_len = (min_len < j - i + 1)? min_len : j - i + 1;
            freq[s[i] - '0']--;
            i++;
            cnt--;
        }

        // Expand window by moving right pointer
        j++;
    }
    return (min_len == INT_MAX)? -1 : min_len;
}

int main()
{
    char s[] = "01212";
    printf("%d\n", smallestSubstring(s));
    return 0;
}
Java
import java.util.Arrays;

class GfG {

    static int smallestSubstring(String s)
    {
        int n = s.length(), i = 0, j = 0, cnt = 0,
            min_len = Integer.MAX_VALUE;

        // Stores frequency of digits 0, 1 and 2 inside
        // current window
        int[] freq = new int[3];

        Arrays.fill(freq, 0);
        while (j < n) {
            freq[s.charAt(j) - '0']++;
            if (freq[s.charAt(j) - '0'] == 1)
                cnt++;
            // When all three digits are present, try to
            // shrink the window
            if (cnt == 3) {
                while (freq[s.charAt(i) - '0'] > 1) {
                    freq[s.charAt(i) - '0']--;
                    i++;
                }

                // Update minimum length of valid substring
                min_len = Math.min(min_len, j - i + 1);
                freq[s.charAt(i) - '0']--;
                i++;
                cnt--;
            }

            // Expand window by moving right pointer
            j++;
        }
        return (min_len == Integer.MAX_VALUE) ? -1
                                              : min_len;
    }

    public static void main(String[] args)
    {
        String s = "01212";
        System.out.println(smallestSubstring(s));
    }
}
Python
def smallestSubstring(s):

    n, i, j, cnt, min_len = len(s), 0, 0, 0, float('inf')

    # Stores frequency of digits 0, 1 and 2 inside current window
    freq = [0] * 3

    while j < n:
        freq[int(s[j])] += 1
        if freq[int(s[j])] == 1:
            cnt += 1

        # When all three digits are present, try to shrink the window
        if cnt == 3:
            while freq[int(s[i])] > 1:
                freq[int(s[i])] -= 1
                i += 1

                # Update minimum length of valid substring
            min_len = min(min_len, j - i + 1)
            freq[int(s[i])] -= 1
            i += 1
            cnt -= 1

        # Expand window by moving right pointer
        j += 1

    return -1 if min_len == float('inf') else min_len


if __name__ == "__main__":

    s = "01212"
    print(smallestSubstring(s))
C#
using System;

class GfG {
    static int smallestSubstring(string s)
    {
        int n = s.Length, i = 0, j = 0, cnt = 0,
            min_len = int.MaxValue;

        // Stores frequency of digits 0, 1 and 2 inside
        // current window
        int[] freq = new int[3];
        Array.Fill(freq, 0);

        while (j < n) {
            freq[s[j] - '0']++;
            if (freq[s[j] - '0'] == 1)
                cnt++;

            // When all three digits are present, try to
            // shrink the window
            if (cnt == 3) {
                while (freq[s[i] - '0'] > 1) {
                    freq[s[i] - '0']--;
                    i++;
                }

                // Update minimum length of valid substring
                min_len = Math.Min(min_len, j - i + 1);
                freq[s[i] - '0']--;
                i++;
                cnt--;
            }

            // Expand window by moving right pointer
            j++;
        }
        return (min_len == int.MaxValue) ? -1 : min_len;
    }

    public static void Main(string[] args)
    {
        string s = "01212";
        Console.WriteLine(smallestSubstring(s));
    }
}
JavaScript
function smallestSubstring(s)
{
    let n = s.length, i = 0, j = 0, cnt = 0,
        min_len = Infinity;

    let freq = [ 0, 0, 0 ];

    while (j < n) {
        freq[parseInt(s[j])] += 1;
        if (freq[parseInt(s[j])] == 1) {
            cnt += 1;
        }

        if (cnt == 3) {
            while (freq[parseInt(s[i])] > 1) {
                freq[parseInt(s[i])] -= 1;
                i += 1;
            }
            min_len = Math.min(min_len, j - i + 1);
            freq[parseInt(s[i])] -= 1;
            i += 1;
            cnt -= 1;
        }
        j += 1;
    }

    return min_len == Infinity ? -1 : min_len;
}

// Driver code
let s = "01212";
console.log(smallestSubstring(s));

Output
3
Comment