原题网址:https://leetcode.com/problems/gray-code/
The gray code is a binary numeral system where two successive values differ in only one bit.
Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0.
For example, given n = 2, return [0,1,3,2]
. Its gray code sequence is:
00 - 0 01 - 1 11 - 3 10 - 2
Note:
For a given n, a gray code sequence is not uniquely defined.
For example, [0,2,3,1]
is also a valid gray code sequence according to the above definition.
For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that.
方法一:观察格雷码的特点,发现每个比特都遵循0110的变化模式,但不同权重的比特,其变化周期不一样,与权重相关。
public class Solution {
public List<Integer> grayCode(int n) {
List<Integer> codes = new ArrayList<>(2<<(n-1));
for(int i=0; i<Math.pow(2, n); i++) {
int code = 0;
for(int j=0; j<n; j++) {
code += (((i>>(j+1))&1) ^ ((i>>j)&1)) << j;
// code += ((i/(int)Math.pow(2,j+1)%2)^(i/(int)Math.pow(2,j)%2)) * (int)Math.pow(2,j);
}
codes.add(code);
}
return codes;
}
}
方法二:根据变动的比特,发现可以用递归直接计算。
public class Solution {
private List<Integer> codes;
private int current;
private void generate(int n) {
for(int i=0; i<n; i++) {
current ^= (1<<i);
codes.add(current);
if (i>0) generate(i);
}
}
public List<Integer> grayCode(int n) {
codes = new ArrayList<>(2<<n);
current = 0;
codes.add(current);
generate(n);
return codes;
}
}
另一种递归实现:
public class Solution {
private int generate(int prev, int n, List<Integer> codes) {
for(int i=0; i<n; i++) {
prev = prev ^ (1<<i);
codes.add(prev);
if (i>0) prev = generate(prev, i, codes);
}
return prev;
}
public List<Integer> grayCode(int n) {
List<Integer> codes = new ArrayList<>();
codes.add(0);
generate(0, n, codes);
return codes;
}
}
另一种递归实现:
public class Solution {
private int gray(int prev, int bit, List<Integer> result) {
int gray = prev ^ (1 << bit);
result.add(gray);
for(int i = 0; i < bit; i++) {
gray = gray(gray, i, result);
}
return gray;
}
public List<Integer> grayCode(int n) {
List<Integer> result = new ArrayList<>();
int gray = 0;
result.add(gray);
for(int i = 0; i < n; i++) {
gray = gray(gray, i, result);
}
return result;
}
}
方法三:将递归方式通过栈来实现。
public class Solution {
public List<Integer> grayCode(int n) {
List<Integer> codes = new ArrayList<>(2<<n);
int current = 0;
codes.add(current);
int[] stack = new int[2<<n];
int pos = 0;
for(int i=n-1; i>=0; i--) stack[pos++] = i;
while (pos > 0) {
pos --;
current ^= (1<<stack[pos]);
codes.add(current);
for(int i=stack[pos]-1; i>=0; i--) stack[pos++] = i;
}
return codes;
}
}