Gray Code
The i-th Gray code is i XOR (i >> 1): XOR the number with itself shifted right by one bit. Loop i from 0 to 2^n − 1 and output each code. There is no search and no visited array, because neighbours i and i + 1 always differ in one bit.
Use code(i) = i XOR (i >> 1) for every i from 0 to 2^n − 1. The codes are all different, and code(i) and code(i + 1) differ in exactly one bit, so the list is valid.
Problem
A Gray code is a list of all n-bit numbers in which every two neighbours differ in exactly one bit.
Build one for a given n. The list must hold every number from 0 to 2^n − 1, each one once, and it must start with 0. Any two neighbours in the list must differ in exactly one bit. The last number must also differ from the first (0) in exactly one bit, so the list can loop round.
Return any list that works.
An integer n.
A list of 2^n integers that forms a valid n-bit Gray code. Any valid list is accepted, so the answer is not unique.
In binary the list is 00, 01, 11, 10. Each step flips one bit. The last step, 10 → 00, flips one bit too, so the list loops. [0, 2, 3, 1] is also accepted.
0 and 1 differ in one bit. The step from 1 back to 0 closes the loop.
- • 1 ≤ n ≤ 16
First, think yourself
Before opening any solution, try to answer these on paper. Use hints only when stuck — each hint is counted.
- 1.
If I list 0, 1, 2, 3 in plain order for n = 2, which neighbouring pair breaks the rule?
- 2.
The list has to hold every number from 0 to 2^n − 1. Does the order matter, or only which numbers appear?
- 3.
From one code, how many codes are exactly one bit away? Can I list the next choices without searching?
- 4.
Is there a rule that gives the i-th code directly, instead of building the list step by step?
- 5.
What must the last code be so that the list loops back to 0?
Brute force approach
Better approach
Optimized approach
Why does this algorithm work?
Dry run
All approaches compared
| Approach | Idea | Time | Space |
|---|---|---|---|
| Brute Force | From 0, flip one bit at a time, never reuse a code, back up when stuck | O(N · 2^N) | O(2^N) |
| Better | Start from [0]; each round, append the list in reverse with the new top bit set | O(2^N) | O(1) |
| Optimal | Code number i is i XOR (i shifted right by one); loop i from 0 to 2^n − 1 | O(2^N) | O(1) |
Why does this belong to this pattern?
- “list all numbers from 0 to 2^n − 1”The set of values is fixed, so only the order is free.
- “neighbours differ in exactly one bit”Each step is a single bit flip: XOR with one power of two.
- “the first and last also differ in one bit”The list must loop, so the wrap pair must be one flip apart too.
Here each state is a bit pattern, and every step flips exactly one bit. This is the anchor of the bitmask sub-pattern: a mask is a state you walk through. What makes this different from Counting Bits or Power of Two is that the order of the values matters, not how many bits they have. The formula works because XOR with a shifted copy turns "flip one bit at a time" into a direct rule.
Don't make this mistake
All the numbers are there, but the order breaks the rule. For n = 2 the plain list is 0, 1, 2, 3. From 1 (01) to 2 (10) flips two bits. The Gray list is 0, 1, 3, 2.
For n = 2 the wrong formula gives 0, 3, 6, 5. The value 6 is outside 0 to 3, so the list is not made of the 2^n codes. The shift has to bring the bit above down, not push bits up.
For n = 2, starting from [0, 1], the reversed copy without the top bit is [1, 0]. The list becomes [0, 1, 1, 0], which repeats 1. Setting the top bit (value 2) makes the copy [3, 2].
For n = 3 the walk 0, 1, 3, 2, 6, 4, 5, 7 uses all 8 codes and flips one bit at each step, but 7 = 111 and 0 differ in three bits. The loop rule is part of the problem, so the last check is needed.
Want to implement this?
Write it yourself on LeetCode, then come back and compare your code with the solutions above.
Open coding workspaceHow this concept connects to System Design & C++ Systems
Top engineering interviews test whether you understand how algorithms like Bit Manipulation translate into production architectures and low-level memory mechanics.
Foundations: Object-Oriented Principles in C++23
Class invariants, pure virtual interfaces, and RAII smart pointers.
Food Delivery System (Zomato Architecture)
Real-world machine coding application of algorithms and design patterns.
Pointers vs References Deep Dive
Pointer arithmetic and memory layout under the hood.
Virtual Method Table (vtable) & Memory Layout
Polymorphism, vptr overhead, and multiple inheritance in memory.