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 }