[LeetCode-JAVA] 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.
原始思路:利用卡诺图生成2进制的格雷码,再转化为十进制。
卡诺图原理:利用卡诺图相邻两格只有一位变化以及卡诺图的变量取值以低阶格雷码的顺序排布的特征,可以递归得到高阶格雷码。由于此方法相对繁琐,使用较少。生成格雷码的步骤如下:
-
将卡诺图变量分为两组,变量数目相近(最好相等)
-
以逻辑变量高位在左低位在右建立卡诺图
-
从卡诺图的左上角以之字形到右上角最后到左下角遍历卡诺图,依次经过格子的变量取值即为典型格雷码的顺序
AB╲ C
|
0
|
1
|
00
|
0→
|
1↓
|
01
|
↓2
|
←3
|
11
|
6→
|
7↓
|
10
|
4
|
←5
|
AB╲CD
|
00
|
01
|
11
|
10
|
00
|
0→
|
1→
|
3→
|
2↓
|
01
|
↓4
|
←5
|
←7
|
←6
|
11
|
12→
|
13→
|
15→
|
14↓
|
10
|
8
|
←9
|
←11
|
←10
|
原始代码:
public class Solution { public List<Integer> grayCode(int n) { List<Integer> req = new ArrayList<Integer>(); String[] gray = factory(n); for(int i = 0 ; i < gray.length ; i++){ String temp = gray[i]; int toInt = binaryToInt(temp); req.add(toInt); } return req; } public String[] factory(int n){ //建立格雷码 String[] req = new String[(int)Math.pow(2, n)]; if( n == 0){ req[0] = "0"; return req; } if( n == 1){ req[0] = "0"; req[1] = "1"; return req; } int up = n/2; //小 int left = n - up; //大 String[] upStr = factory(up); String[] leftStr = factory(left); int len = 0; for(int i = 0 ; i < leftStr.length ; i++){ for(int j = 0 ; j < upStr.length ; j++){ req[len] = leftStr[i] + upStr[j]; len++; } i++; for(int j = upStr.length-1 ; j >= 0 ; j--){ req[len] = leftStr[i] + upStr[j]; len++; } } return req; } public int binaryToInt(String str){ //2进制转化为十进制 int count = 0; int len = str.length(); for(int i = 0 ; i < len ; i++){ int temp = str.charAt(i) - '0'; if(temp == 0) continue; else count += (int)Math.pow(2,len-1-i); } return count; } }
改进思路:利用新的生成原理,可以看到n位的格雷码由两部分构成,一部分是n-1位格雷码,再加上 1<<(n-1)和n-1位格雷码的逆序(整个格雷码逆序0132变成2310这种)的和。
原文链接:http://www.cnblogs.com/springfor/p/3889222.html?utm_source=tuicool
改进代码:
public class Solution { public List<Integer> grayCode(int n) { if(n==0){ List<Integer> req = new ArrayList<Integer>(); req.add(0); return req; } List<Integer> req = grayCode(n-1); int addNumber = 1<<n-1; int preSize = req.size(); for(int i = preSize-1 ; i>=0 ; i--){ req.add(addNumber + req.get(i)); } return req; } }