C# 力扣_格雷编码

题目链接
n 位格雷码序列 是一个由 2n 个整数组成的序列,其中:
每个整数都在范围 [0, 2n - 1] 内(含 0 和 2n - 1)
第一个整数是 0
一个整数在序列中出现 不超过一次
每对 相邻 整数的二进制表示 恰好一位不同 ,且
第一个 和 最后一个 整数的二进制表示 恰好一位不同
给你一个整数 n ,返回任一有效的 n 位格雷码序列 。

我的代码

public IList<int> GrayCode(int n)
		{
			List<int> res = new List<int>();
			res.Add(0);
			int lens = (int)Math.Pow(2, n);
			ValueTuple<int, bool, int[]>[] alls = new ValueTuple<int, bool, int[]>[lens];
			myfun(n, alls);
			alls[0].Item2 = true;
			myfun2(n, alls, res);
			return res;
		}
		public void myfun(int n, ValueTuple<int, bool, int[]>[] alls)
		{
			for (int i = 0; i < alls.Length; i++)
			{
				alls[i] = new ValueTuple<int, bool, int[]>(i, false, new int[n]);
				string str = Convert.ToString(i, 2).PadLeft(n, '0');
				for (int j = 0; j < n; j++)
				{
					char[] ch = str.ToCharArray();
					ch[j] = ch[j] == '0' ? '1' : '0';
					alls[i].Item3[j] = Convert.ToInt32(new string(ch), 2);
				}
			}
		}
		public bool myfun2(int n, ValueTuple<int, bool, int[]>[] alls, List<int> res)
		{
			if (res.Count == alls.Length) return true;
			int index = res[res.Count - 1];
			bool isover = false;
			for (int i = 0; i < n; i++)
			{
				int num = alls[index].Item3[i];
				if (alls[num].Item2 == true) continue;
				res.Add(num);
				alls[num].Item2 = true;
				isover= myfun2(n, alls, res);
				if (isover == false)
				{
					res.RemoveAt(res.Count - 1);
					alls[num].Item2 = false;
				}
				else return true;
			}
			return false;
		}

代码思路

  • 首先观察到每个数字的下一数字只可能有n个,分别是对应二进制中各个位上的一次取反。
  • 然后根据数据结构领接矩阵的思想,深度递归构建的矩阵。
  • 就算是算法本人,我也解释不了,为什么这么做,最后一个数字一定会和0满足格雷编码的条件。
  • 更严谨的做法是,最后加上判断。

官方代码

public class Solution {
    public IList<int> GrayCode(int n) {
        IList<int> ret = new List<int>();
        ret.Add(0);
        for (int i = 1; i <= n; i++) {
            int m = ret.Count;
            for (int j = m - 1; j >= 0; j--) {
                ret.Add(ret[j] | (1 << (i - 1)));
            }
        }
        return ret;
    }
}

官方思路

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值