mthoutai

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
问题概述:
在一组数的编码中,若随意两个相邻的代码仅仅有一位二进制数不同。则称这样的编码为格雷码。


2位数的格雷码序列:
00 : 0
01 : 1
11 : 3
10 : 2
找规律:
假设要求n位的格雷码,先要求出n-1位的格雷码。


循环上一次格雷码的每一位,都会生成两个新的格雷码: 
统计'1'出现的次数
假设为偶数: 两个新格雷码分别为xxx1和xxx0
假设为奇数: 两个新格雷码分别为xxx0和xxx1


以3位格雷码为例:


由00得:
000 = 00+(0)
001 = 00+(1)


由01得:
011 = 01+(1)
010 = 01+(0)


由11得:
110 = 11+(0)
111 = 11+(1)


由10得:
101 = 10+(1)
100 = 10+(0)


然后把新格雷码加入到序列用于下一次格雷码序列的计算。

实现代码:



public class Solution {
    public IList<int> GrayCode(int n) {
    if(n < 0){
		return new List<int>();
	}
	if(n == 0){
	    return new List<int>{0};
	}
	if(n == 1){
		return new List<int>(){0,1};
	}
	if(n == 2){
		return new List<int>{0,1,3,2};
	}
	
	var r = new List<string>(){"00","01","11","10"};
	for(var i = 3;i <= n; i++){
		var tmp = new List<string>();
		for(var j = 0;j < r.Count; j++){
			var countOne = 0;
			foreach(var c in r[j]){
				if(c == '1'){
					countOne ++;
				}
			}
			if(countOne % 2 == 0){
				tmp.Add(r[j]+"0");
				tmp.Add(r[j]+"1");
			}
			else{
				tmp.Add(r[j]+"1");
				tmp.Add(r[j]+"0");
			}
		}
		r = tmp;
	}
	
	var ret = new List<int>();
	foreach(var s in r){
		var num = Convert.ToInt32(s,2);
		ret.Add(num);
	}
	
	return ret;
	
    }
}


posted on 2017-04-29 19:21  mthoutai  阅读(369)  评论(0编辑  收藏  举报