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 }
思路为,假设我们已经找到 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 }
原文:http://www.cnblogs.com/Phoenix-Fearless/p/5117725.html