【回溯】【leetcode】格雷编码

题目:

格雷编码是一个二进制数字系统,在该系统中,两个连续的数值仅有一个位数的差异。

给定一个代表编码总位数的非负整数 n,打印其格雷编码序列。即使有多个不同答案,你也只需要返回其中一种。

格雷编码序列必须以 0 开头。

示例 1:

输入: 2
输出: [0,1,3,2]
解释:
00 - 0
01 - 1
11 - 3
10 - 2

对于给定的 n,其格雷编码序列并不唯一。
例如,[0,2,3,1] 也是一个有效的格雷编码序列。

00 - 0
10 - 2
11 - 3
01 - 1

来源:

89. 格雷编码

解题思路1:回溯

定义一个path存储中间结果,一旦满足条件立即输出。

  • 结果满足条件:path中数量已达
  • 递归调用条件:前一数字的各个格雷编码如果不在path中,则递归。

当前数字假如为000,它下一个格雷编码可以是001,010,100。着重说一下代码中的gray函数,修改第p位并返回:先判断第p位数字是0或1,如果0,或操作可修改为1;如果是1,与操作可修改为0。

class Solution {
public:
    vector<int> result;
    vector<int> path;
    bool ok;
    vector<int> grayCode(int n) {
        vector<bool> flag(1<<n, false); // 记录数字是否已在结果列表中
        ok = false;
        path.push_back(0);
        flag[0] = true;
        back(n, flag);
        return result;
    }
    void back(int n, vector<bool>& flag) {
        if (path.size() == flag.size()) {
            result = path;
            ok = true;
            return;
        }
        int pre = path[path.size() - 1]; // 结果列表中最后一个数字
        for (int i = 0; i < n; i++) {
            if (ok) break;
            int k = gray(pre, i); // 最后一个数字的改变第i位后的数字
            if (!flag[k]) {
                flag[k] = true;
                path.push_back(k);
                back(n, flag);
                path.pop_back();
                flag[k] = false;
            }
        }
    }
    int gray(int v, int p) {
        int a = (0x1 << p);
        if ((a & v) == 0) {
            return v | a;
        } else {
            return v & (~a);
        }
    }
};

解题思路2:找规律

将回溯代码提交发现,运行效率很低:执行用时:20 ms, 在所有 C++ 提交中击败了12.37%的用户。

好奇的我去看了题解,发现本题还是有规律可循的,没写代码,我把发现的规律列在下面:

当n=1时,结果是[0,1],

当n=2时,分3步:

  1. 将n=1的结果拿过来得到[0,1]。
  2. 将[0,1]照一下镜子复制一份得到[1,0],二者合并得[0,1 | 1, 0],中间加了一个符号|,暂且称它为镜子。
  3. 镜子左侧每个数字开头添加0,右侧添加1,得[00, 01 | 11, 10],此即为结果

当n=3,4,5...时,依次重复上面3步。

当n=3时,

  1. 将n=2的结果拿过来得到[00, 01, 11, 10]。
  2. 将[00, 01, 11, 10]照一下镜子复制一份得到[10, 11, 01, 00],二者合并得[00, 01, 11, 10 | 10, 11, 01, 00]。
  3. 镜子左侧每个数字开头添加0,右侧添加1,得[000, 001, 011, 010 | 110, 111, 101, 100],此即为结果

猜你喜欢

转载自blog.csdn.net/hbuxiaoshe/article/details/115123734