首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

LeetCode Gray Code 格雷碼:遞歸構造與位運算公式兩種解法

     編輯:C++ 入門

問題描述

給定非負整數 n,生成 n 位元格雷碼序列。格雷碼特性:相鄰兩碼僅差 1 位,且必以 0 開頭。

範例

n = 2: [0, 1, 3, 2]
二進位: 00, 01, 11, 10  ← 每步僅翻轉 1 位

另一合法解: [0, 2, 3, 1] (00, 10, 11, 01)

解法一:遞歸鏡像構造

核心洞察

n 位格雷碼可由 n-1 位構造:

  1. 取 n-1 位序列
  2. 鏡像反轉
  3. 前半加前綴 0,後半加前綴 1(即加 1 << (n-1))
  4. 拼接

Java 實作

import java.util.ArrayList;

public class GrayCode {
    public ArrayList<Integer> grayCode(int n) {
        ArrayList<Integer> res = new ArrayList<>();
        res.add(0);  // n=0 時序列
        
        for (int i = 1; i <= n; ++i) {
            int prefix = 1 << (i - 1);  // 最高位掩碼
            int size = res.size();
            // 逆序遍歷原序列,加上前綴
            for (int j = size - 1; j >= 0; --j) {
                res.add(res.get(j) + prefix);
            }
        }
        return res;
    }
}

演示過程 (n=3)

i=1: [0] → [0, 1]           (前綴 1)
i=2: [0, 1] → [0, 1, 3, 2]  (前綴 2)
i=3: [0, 1, 3, 2] → [0, 1, 3, 2, 6, 7, 5, 4]  (前綴 4)

解法二:格雷碼編碼公式

數學公式

第 i 個格雷碼:G(i) = i ^ (i >> 1)

  • i >> 1:右移一位
  • ^:異或運算

Java 實作

public class GrayCode2 {
    public ArrayList<Integer> grayCode(int n) {
        ArrayList<Integer> res = new ArrayList<>();
        int total = 1 << n;  // 2^n
        for (int i = 0; i < total; ++i) {
            res.add((i >> 1) ^ i);
        }
        return res;
    }
}

公式驗證 (n=3)

i二進位i>>1異或結果十進位
00000000000
10010000011
20100010113
30110010102
41000101106
51010101117
61100111015
71110111004

兩種解法比較

維度遞歸鏡像位運算公式
時間複雜度O(2^n)O(2^n)
空間複雜度O(2^n)O(2^n)
理解難度直觀易懂需知公式
程式碼長度較長極短
擴展性易於生成路徑僅生成序列

格雷碼應用場景

  1. 卡諾圖簡化:相鄰格僅差一變數
  2. 旋轉編碼器:避免多位同時翻轉導致誤讀
  3. 漢諾塔最優解:移動步驟對應格雷碼序列
  4. 基因演算法:編碼鄰近性保持
  5. 誤差校正:最小化狀態轉換錯誤

解碼:格雷碼 → 二進位

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved