Open In App

CSES Solutions – Gray Code

Last Updated : 02 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

A Gray code is a list of all 2n bit strings of length n, where any two successive strings differ in exactly one bit (i.e., their Hamming distance is one).

Your task is to create a Gray code for a given length n.

Examples:

Input: n=2
Output: {“00”, “01”, “11”, “10”}

Input: n=1
Output: {“0”, “1”}

Approach: Follow the below approach to solve the problem

The idea is to solve the problem recursively.

We have to generate list of 2n binary strings where any two successive strings differ in exactly one bit. Now suppose we know the answer for n-1, i.e., we are able to generate 2n-1 binary strings. To extend this list to 2n binary string we first store the list of 2n-1 binary strings temporarly and reverse the order of the strings. Next, we prepend ‘0’ to each string in the original list and ‘1’ to each string in the reversed list. Finally, we concatenate these modified lists to obtain the Gray code for length n. Let’s consider the example

  • For n=1, the list will be {“0”, “1”}
  • For n=2, we will extend the above list. Notice that to genrate all strings we will have to prepend ‘0’ and ‘1’ at the start. We have two list one generated after prepending ‘0’ which gives {“00”, “01”}, and another after prepending ‘1’ which gives {“10”, “11”}. The two successive strings differ in exactly one bit in both the list, and it can be noticed that last strings in both the list differ by 1 bit, so we will reverse the 2nd list and add it into the first one.

Follow the steps to solve the problem:

  • The problem is solved using recursive function.
  • The base case of the recursion is when n is 1. In this case, the function returns the list {“0”, “1”}.
  • For n greater than 1, the function recursively calls generateGrayCode(n - 1) to obtain the list of 2(n-1) binary strings, denoted as prevGrayCode.
  • The original list prevGrayCode is stored temporarily in reversedPrevGrayCode and the order of reversedPrevGrayCode is reversed using reverse().
  • Iterate through the original list prevGrayCode.
    • For each string, prepend ‘0’ to it, updating the string in place.
    • Simultaneously, prepend ‘1’ to the corresponding string in the reversed list reversedPrevGrayCode.
  • Concatenate the modified list with the original list prevGrayCode to obtain the Gray code for length n.

Below is the implementation of above approach:

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

vector<string> generateGrayCode(int n)
{
    // Base Case 
    if (n == 1)
    {
        return {"0", "1"};
    }
  
      // Calculate the strings for n-1 length 
    vector<string> prevGrayCode = generateGrayCode(n - 1);
      
      // Reverse the previous Gray Code for n-1 length
    vector<string> reversedPrevGrayCode = prevGrayCode;
    reverse(reversedPrevGrayCode.begin(), reversedPrevGrayCode.end());
  
    int prevSize = prevGrayCode.size();
    int index = 0;
    while (index < prevSize)
    {
          // Prepend the character 0 in previous Gray Codes
        string appendedZero = "0" + prevGrayCode[index];
   
        // Prepend the character 1 in Reversed previous Gray Codes
        prevGrayCode[index] = "1" + reversedPrevGrayCode[index];
        prevGrayCode.push_back(appendedZero);
        index++;
    }
    return prevGrayCode;
}

int main()
{
    int n = 2;
    vector<string> grayCode = generateGrayCode(n);
    for (auto code : grayCode)
        cout << code << "\n";
    return 0;
}
Java
import java.util.ArrayList;
import java.util.List;

public class GFG {
    public static List<String> generateGrayCode(int n) {
        // Base Case: If n is 1 and return ["0", "1"]
        if (n == 1) {
            List<String> grayCode = new ArrayList<>();
            grayCode.add("1");
            grayCode.add("0");
            return grayCode;
        }
        // Recursively calculate the Gray codes for n-1 length
        List<String> prevGrayCode = generateGrayCode(n - 1);
        List<String> reversedPrevGrayCode = new ArrayList<>(prevGrayCode);
        java.util.Collections.reverse(reversedPrevGrayCode);     
        // Initialize a list to the store the current Gray codes
        List<String> currentGrayCode = new ArrayList<>(prevGrayCode);       
        for (int i = 0; i < prevGrayCode.size(); i++) {
            // Prepend "1" to reversed previous Gray Codes
            currentGrayCode.set(i, "0" + reversedPrevGrayCode.get(i));        
            prevGrayCode.set(i, "1" + prevGrayCode.get(i));
        }       
        // Concatenate the modified "0" version to the previous Gray Codes
        prevGrayCode.addAll(currentGrayCode);       
        return prevGrayCode;
    }
    // Main method
    public static void main(String[] args) {
        int n = 2;
        List<String> grayCode = generateGrayCode(n);
        for (String code : grayCode) {
            System.out.println(code);
        }
    }
}
Python
def generateGrayCode(n):
    # Base Case: If n is 1, return ["0", "1"]
    if n == 1:
        return ["0", "1"]
    
    # Recursively calculate the Gray codes for n-1 length
    prevGrayCode = generateGrayCode(n - 1)
    
    # Reverse the previous Gray Code for n-1 length
    reversedPrevGrayCode = prevGrayCode[::-1]
    
    prevSize = len(prevGrayCode)
    index = 0
    while index < prevSize:
        # Prepend "0" to the previous Gray Codes
        appendedZero = "0" + prevGrayCode[index]
        
        # Prepend "1" to the reversed previous Gray Codes
        prevGrayCode[index] = "1" + reversedPrevGrayCode[index]
        
        # Append the modified "0" version to the previous Gray Codes
        prevGrayCode.append(appendedZero)
        index += 1
    
    return prevGrayCode

# Main function
if __name__ == "__main__":
    n = 2
    grayCode = generateGrayCode(n)
    for code in grayCode:
        print(code)
JavaScript
function GFG(n) {
    // Base Case: If n is 1, return ["0", "1"]
    if (n === 1) {
        return ["1", "0"];
    }
    // Recursively calculate the Gray codes for the n-1 length
    let prevGrayCode = GFG(n - 1);
    let reversedPrevGrayCode = prevGrayCode.slice().reverse();
    let currentGrayCode = prevGrayCode.slice();
    // Generate new Gray codes by prepending "0" to the reversed previous Gray codes
    // and prepending "1" to the original previous Gray codes
    for (let i = 0; i < prevGrayCode.length; i++) {
        currentGrayCode[i] = "0" + reversedPrevGrayCode[i];
        prevGrayCode[i] = "1" + prevGrayCode[i];
    }
    // Concatenate the modified "0" version to previous Gray codes
    prevGrayCode = prevGrayCode.concat(currentGrayCode);
    return prevGrayCode;
}
// Main function
function main() {
    let n = 2;
    let grayCode = GFG(n);
    for (let code of grayCode) {
        console.log(code);
    }
}
// Call the main function
main();

Output
11
10
00
01

Time Complexity: O(2n)
Auxilary Space: O(2n)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads