De Bruijn sequence | Set 1

Last Updated : 11 Jul, 2025

Given an integer n and a set of characters A of size k, find a string S such that every possible string on A of length n appears exactly once as a substring in S. Such a string is called de Bruijn sequence.

Examples: 

Input: n = 3, k = 2, A = {0, 1) 
Output: 0011101000 
All possible strings of length three (000, 001, 010, 011, 100, 101, 110 and 111) appear exactly once as sub-strings in A.

Input: n = 2, k = 2, A = {0, 1) 
Output: 01100 

Approach: 
We can solve this problem by constructing a directed graph with kn-1 nodes with each node having k outgoing edges. Each node corresponds to a string of size n-1. Every edge corresponds to one of the k characters in A and adds that character to the starting string. 

For example, if n=3 and k=2, then we construct the following graph:
 

  • The node '01' is connected to node '11' through edge '1', as adding '1' to '01' (and removing the first character) gives us '11'.
  • We can observe that every node in this graph has equal in-degree and out-degree, which means that a Eulerian circuit exists in this graph.
  • The Eulerian circuit will correspond to a de Bruijn sequence as every combination of a node and an outgoing edge represents a unique string of length n.
  • The de Bruijn sequence will contain the characters of the starting node and the characters of all the edges in the order they are traversed in.
  • Therefore the length of the string will be kn+n-1. We will use Hierholzer’s Algorithm to find the Eulerian circuit. The time complexity of this approach is O(kn).

Below is the implementation of the above approach:  

C++
// C++ implementation of
// the above approach
#include <bits/stdc++.h>
using namespace std;

unordered_set<string> seen;
vector<int> edges;

// Modified DFS in which no edge
// is traversed twice
void dfs(string node, int& k, string& A)
{
    for (int i = 0; i < k; ++i) {
        string str = node + A[i];
        if (seen.find(str) == seen.end()) {
            seen.insert(str);
            dfs(str.substr(1), k, A);
            edges.push_back(i);
        }
    }
}

// Function to find a de Bruijn sequence
// of order n on k characters
string deBruijn(int n, int k, string A)
{

    // Clearing global variables
    seen.clear();
    edges.clear();

    string startingNode = string(n - 1, A[0]);
    dfs(startingNode, k, A);

    string S;

    // Number of edges
    int l = pow(k, n);
    for (int i = 0; i < l; ++i)
        S += A[edges[i]];
    S += startingNode;

    return S;
}

// Driver code
int main()
{
    int n = 3, k = 2;
    string A = "01";

    cout << deBruijn(n, k, A);

    return 0;
}
Java
// Java implementation of
// the above approach
import java.util.*;

class GFG
{

    static Set<String> seen = new HashSet<String>();
    static Vector<Integer> edges = new Vector<Integer>();

    // Modified DFS in which no edge
    // is traversed twice
    static void dfs(String node, int k, String A) 
    {
        for (int i = 0; i < k; ++i)
        {
            String str = node + A.charAt(i);
            if (!seen.contains(str))
            {
                seen.add(str);
                dfs(str.substring(1), k, A);
                edges.add(i);
            }
        }
    }

    // Function to find a de Bruijn sequence
    // of order n on k characters
    static String deBruijn(int n, int k, String A)
    {

        // Clearing global variables
        seen.clear();
        edges.clear();

        String startingNode = string(n - 1, A.charAt(0));
        dfs(startingNode, k, A);

        String S = "";

        // Number of edges
        int l = (int) Math.pow(k, n);
        for (int i = 0; i < l; ++i)
            S += A.charAt(edges.get(i));
        S += startingNode;

        return S;
    }

    private static String string(int n, char charAt)
    {
        String str = "";
        for (int i = 0; i < n; i++)
            str += charAt;
        return str;
    }

    // Driver code
    public static void main(String[] args) 
    {
        int n = 3, k = 2;
        String A = "01";

        System.out.print(deBruijn(n, k, A));
    }
}

// This code is contributed by 29AjayKumar
Python3
# Python3 implementation of
# the above approach
import math 

seen = set()
edges = []

# Modified DFS in which no edge
# is traversed twice
def dfs( node, k, A):
    
    for i in range(k):
        str = node + A[i]
        if (str not in seen):
            seen.add(str)
            dfs(str[1:], k, A)
            edges.append(i)

# Function to find a de Bruijn sequence
# of order n on k characters
def deBruijn(n, k, A):
    
    # Clearing global variables
    seen.clear()
    edges.clear()
    
    startingNode = A[0] * (n - 1)
    dfs(startingNode, k, A)
    
    S = ""
    
    # Number of edges
    l = int(math.pow(k, n))
    for i in range(l):
        S += A[edges[i]]
        
    S += startingNode
    return S

# Driver code
n = 3
k = 2
A = "01"

print(deBruijn(n, k, A))

# This code is contributed by shubhamsingh10
C#
// C# implementation of 
// the above approach 
using System;
using System.Collections.Generic;

class GFG 
{ 

    static HashSet<String> seen = new HashSet<String>(); 
    static List<int> edges = new List<int>(); 

    // Modified DFS in which no edge 
    // is traversed twice 
    static void dfs(String node, int k, String A) 
    { 
        for (int i = 0; i < k; ++i) 
        { 
            String str = node + A[i]; 
            if (!seen.Contains(str)) 
            { 
                seen.Add(str); 
                dfs(str.Substring(1), k, A); 
                edges.Add(i); 
            } 
        } 
    } 

    // Function to find a de Bruijn sequence 
    // of order n on k characters 
    static String deBruijn(int n, int k, String A) 
    { 

        // Clearing global variables 
        seen.Clear(); 
        edges.Clear(); 

        String startingNode = strings(n - 1, A[0]); 
        dfs(startingNode, k, A); 

        String S = ""; 

        // Number of edges 
        int l = (int) Math.Pow(k, n); 
        for (int i = 0; i < l; ++i) 
            S += A[edges[i]]; 
        S += startingNode; 

        return S; 
    } 

    private static String strings(int n, char charAt) 
    { 
        String str = ""; 
        for (int i = 0; i < n; i++) 
            str += charAt; 
        return str; 
    } 

    // Driver code 
    public static void Main(String[] args) 
    { 
        int n = 3, k = 2; 
        String A = "01"; 

        Console.Write(deBruijn(n, k, A)); 
    } 
} 

// This code is contributed by 29AjayKumar
JavaScript
<script>

// Javascript implementation of 
// the above approach 
var seen = new Set(); 
var edges = []; 

// Modified DFS in which no edge 
// is traversed twice 
function dfs(node, k, A) 
{ 
    for (var i = 0; i < k; ++i) 
    { 
        var str = node + A[i]; 
        if (!seen.has(str)) 
        { 
            seen.add(str); 
            dfs(str.substring(1), k, A); 
            edges.push(i); 
        } 
    } 
} 

// Function to find a de Bruijn sequence 
// of order n on k characters 
function deBruijn(n, k, A) 
{ 

    // Clearing global variables 
    seen = new Set(); 
    edges = []; 
    var startingNode = A[0].repeat(n-1); 
    dfs(startingNode, k, A); 
    var S = ""; 
    
    // Number of edges 
    var l = Math.pow(k, n); 
    for (var i = 0; i < l; ++i) 
        S += A[edges[i]]; 
    S += startingNode; 
    return S; 
} 
function strings(n, charAt) 
{ 
    var str = ""; 
    for (var i = 0; i < n; i++) 
        str += charAt; 
    return str; 
} 

// Driver code 
var n = 3, k = 2; 
var A = "01"; 
document.write(deBruijn(n, k, A)); 

// This code is contributed by rrrtnx.
</script>

Output
0011101000
Comment