java gray code_89. Gray Code - LeetCode

Question

20180626162932.png

Solution

思路:

n = 0 0

n = 1 0 1

n = 2 00 01 10 11

n = 3 000 001 010 011 100 101 110 111

Java实现:

public List grayCode(int n) {

List list = new ArrayList<>();

grayCode(n, 0, list);

return list;

}

void grayCode(int n, int cur, List list) {

if (cur == 0) {

list.add(0);

} else if (cur == 1) {

list.add(1);

} else {

int tmpSize = list.size();

for (int i = tmpSize - 1; i >= 0; i--) {

// int tmp = 1 << (cur - 1);

// System.out.println(tmp + "\t" + list.get(i) + "\t" + (list.get(i) | tmp));

list.add(list.get(i) | (1 << (cur - 1)));

}

}

if (cur < n) grayCode(n, cur + 1, list);

}

Reference

格雷码是很经典的问题,规则其实很简单,在二进制形式下,任何响铃的两个值的二进制表示形式只有一位是不同的,我们可以找找规律。

一位就是简单的:0,1

两位是:00,01,11,10

三位是:000,001,011,010,110,111,101,100

发现什么规律没有?我们把一位的两个数,前面加上0,就是二位的头两个数,前面加上1再反序,就是二位的后两个数。把二位的前面加上0,就是三位的头四个数,把二位的前面加上1再反过来,就是三位的后四个数。

也就是说,对于每多一位的格雷码,前面一半的第一位都是0,后面一半的第一位都是1,其余的位,前后两半正好是中间对称的,前面一半就是少一位的格雷码序列,后面一半时把其反序。

知道这个规律就好做了,我们可以递归来做,每次取n-1位的格雷码来做上述操作,对于一位的格雷码,直接赋值是0,1就可以了。

不过题目要求返回的是十进制数,而不是字符串,所以我们最好直接操作十进制数,这里前面加0其实就不用做什么,前面加1的话可以将1左移n-1位然后与各个数字相加即可。

注意题目说的n是非负数,所以要考虑n=0的情况,测试用例的n=0时返回的是0。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值