1. Backtracking (DFS Search)
Intuition
Maintain a visited set and current path starting with 0. At each step, try flipping bits 0 through n - 1. If the new number hasn't been visited, recurse. Backtrack if dead end is hit.
When to apply: When understanding the graph-theoretic formulation of Gray codes.
Algorithm
- Step 1: Initialize visited set with 0, path with [0].
- Step 2: Try flipping bit j from 0 to n - 1.
- Step 3: If flipped value unvisited, recurse.
- Step 4: If path length reaches 2n, solution found.
#include <iostream>#include <vector>#include <unordered_set> using namespace std; bool dfs(int n, int total, vector<int>& path, unordered_set<int>& visited) { if ((int)path.size() == total) return true; int curr = path.back(); for (int j = 0; j < n; ++j) { int nextVal = curr ^ (1 << j); if (!visited.count(nextVal)) { visited.insert(nextVal); path.push_back(nextVal); if (dfs(n, total, path, visited)) return true; path.pop_back(); visited.erase(nextVal); } } return false;} vector<int> grayCodeDFS(int n) { int total = 1 << n; vector<int> path = {0}; unordered_set<int> visited = {0}; dfs(n, total, path, visited); return path;} int main() { auto res = grayCodeDFS(2); for (int v : res) cout << v << " "; cout << endl; // 0 1 3 2 return 0;}Time & Space Complexity
- Time complexity:
O(n * 2^n) - Space complexity:
O(2^n) visited set & recursion stack