Gray Code

Question: 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.


 分析:

这里采用了比较经典的 Backtracking。

这里 Assume 当 n 为 0 时,返回的是[0]. 

因为题目中只要求找出一个满足要求的序列就 OK,所以这个题目的题解找寻Solution 数字之间的规律更为 efficient。但是,如果是要求输出全部满足条件的序列 List<List<Integer>>, BackingTrachking 就是正解,只需将 helper 的返回类型变为 void,delete 原 return false/true 处即可。 

 1 public class Solution {
 2     public List<Integer> grayCode(int n) {
 3         LinkedList<Integer> res = new LinkedList<>();
 4         if(n < 0) {
 5             return res;
 6         } 
 7         
 8         int[] buff = new int[n];
 9         Set<Integer> set = new HashSet<>();
10         set.add(0);
11         res.add(0);
12         helper(buff, set, res);
13         
14         return res;
15     }
16     
17     private boolean helper(int[] buff, Set<Integer> set, LinkedList<Integer> res) {
18         if(set.size() == (1 << buff.length)) {
19             return true;
20         }
21         
22         // for(int i = 0; i < buff.length; i++) {           
23         // Both work, but different integer order
24         for(int i = buff.length - 1; i >= 0; i--) {
25             buff[i] ^= 1;
26             int val = toIntVal(buff);
27             if(set.contains(val)) {
28                 buff[i] ^= 1;
29                 continue;
30             }
31             
32             set.add(val);
33             res.add(val);
34             
35             if(helper(buff, set, res)) {
36                 return true;
37             }
38             
39             buff[i] ^= 1;
40             set.remove(val);
41             res.removeLast();
42         }
43         
44         return false;
45     }
46     
47     private int toIntVal(int[] array) {
48         int res = 0;
49         for(int i : array) {
50             res = (res << 1) + i;
51         }
52         return res;
53     }
54 }    

Solution 2: Referred from Code Ganker.

思路为,假设我们已经找到 f(n) 对应的序列,那么 f(n+1) 对应的序列,the first half 就是 f(n) 对应的序列,即最高位为0;而 second half 是 f(n) 的对应序列的反向,最高位为1. 如此就有了相应的递推关系。

Code并不难写:这里的 Recursion 是可以采用 Iteration 来实现的。

 1 public class Solution {
 2     public List<Integer> grayCode(int n) {
 3         ArrayList<Integer> res = new ArrayList<>();
 4         if(n < 0) {
 5             return res;
 6         } else if(n == 0) {
 7             res.add(0);
 8             return res;
 9         } 
10         
11         res.add(0);
12         res.add(1);
13         helper(1, n, res);
14 
15         return res;
16     }
17     
18     private void helper(int i, int n, ArrayList<Integer> res) {
19         if(i == n) {
20             return;
21         }
22         
23         int index = (1 << i ) - 1;
24         int mask = 1 << i;
25         while(index >= 0) {
26             res.add(res.get(index) ^ mask);
27             index--;
28         }
29         helper(i+1, n, res);
30     }
31 }
原文地址:https://www.cnblogs.com/Phoenix-Fearless/p/5117725.html