格雷编码是一个二进制数字系统,在该系统中,两个连续的数值仅有一个位数的差异。
给定一个代表编码总位数的非负整数 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
示例 2:
输入: 0 输出: [0] 解释: 我们定义格雷编码序列必须以 0 开头。 给定编码总位数为 n 的格雷编码序列,其长度为 2n。当 n = 0 时,长度为 20 = 1。 因此,当 n = 0 时,其格雷编码序列为 [0]。
Java最简单的版本 简单分析,详细注解
简单分析:
- 我们举几个例子来看一下。
- 当n=1时,为[0,1]
- 当n=2时,为[00,01,11,10]
- 当n=3时,为[000,001,011,010,110,111,101,100]
- 如果把前面的0都去掉,就变成:
- 当n=1时,为[0,1]
- 当n=2时,为[0,1,11,10]
- 当n=3时,为[0,1,11,10,110,111,101,100]
- 有没有发现什么规律呢?
- 原来,第n层的数是建立在n-1层的基础上,第n层的前半部分跟n-1层的全部元素一样。后半部分,就是在前半部分的基础上最高位加个1.
- 这样以来,怎么样在最高位加1呢。那就利用异或运算。将当前的数和它的二分之一(num>>1)做异或,这样,因为当前的数比它的二分之一在最高位上多了个1,所以,这就是要添加的下一个数。
- OK,可以写代码了
public ArrayList<Integer> grayCode(int n) { ArrayList<Integer> res = new ArrayList<>(); int num = 1 << n; for (int i = 0; i < num; i++) { res.add(i >> 1 ^ i); } return res; }