🌈【LeetCode 89. 格雷编码 】- JavaScript(递归+规律)

155 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第12天,点击查看活动详情


说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)

作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金

GitHub:P-J27、 CSDN:PJ想做前端攻城狮

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


【LeetCode 89. 格雷编码 】- JavaScript(递归+规律)

题目描述

n 位格雷码序列 是一个由 2n 个整数组成的序列,其中:

  • 每个整数都在范围 [0, 2n - 1] 内(含 0 和 2n - 1)
  • 第一个整数是 0
  • 一个整数在序列中出现 不超过一次
  • 每对 相邻 整数的二进制表示 恰好一位不同 ,且
  • 第一个 和 最后一个 整数的二进制表示 恰好一位不同

给你一个整数 n ,返回任一有效的 n 位格雷码序列 。

示例 1:

输入:n = 2 输出:[0,1,3,2] 解释: [0,1,3,2] 的二进制表示是 [00,01,11,10] 。

  • 00 和 01 有一位不同
  • 01 和 11 有一位不同
  • 11 和 10 有一位不同
  • 10 和 00 有一位不同 [0,2,3,1] 也是一个有效的格雷码序列,其二进制表示是 [00,10,11,01] 。
  • 00 和 10 有一位不同
  • 10 和 11 有一位不同
  • 11 和 01 有一位不同
  • 01 和 00 有一位不同

递归+规律

思路分析:

整体的的思路:对于这种构造类型的问题方面,我们都知道是可以按照一定规律逐步构造的,既然能够逐步构造,说明问题是从子问题开始逐渐解决,应该是可以使用递归解决的。然后我们就进行创建格雷码来发现规律,创建时就尽量让它有规律。如下

n = 0: 0
n = 1: 0 1
n = 2: 00 01 11 10
n = 3: 000 001 011 010 110 111 101 100

我们可以发现n位的gray码的构造就是在n-1位的情况下原序列头部补零,紧接着反序列头部补1。更直白一点就是这样的。

  • 当n=2时,masks等于1,2
  • 当n=3时,mask是等于1,2,4
  • 当n=4时,masks等于1,2,4,8

这样就构造出了有规律的问题求解过程,可以使用递归解决。那么我们的解题步骤也出来了如下

  1. 问题基例:n=0时,结果为[0]
  2. 子问题模型:n位的结果 = n-1位的结果补零,n-1位的结果反序列补1(移位解决)
var grayCode = function(n) {
  if (n === 0) { return [0]; }
  if (n === 1) { return [0, 1]; }
  const res = [];
  recureGrayCode(n, res);
  return res.map((item) => parseInt(item, 2));
};

function recureGrayCode(n, res = [], index = 0, tmp = "") {
  if (index === n) {
    res.push(tmp);
    return;
  }
  let nexts = (res[res.length - 1] || "").slice(0, index) || "";
  let cur = (res[res.length - 1] || "")[index] || "";
  recureGrayCode(n, res, index + 1, `${tmp}${nexts!=="" ? (!(nexts ^ tmp) ? (cur !== "1" ? "1" : "0") : cur) : "0"}`);
  nexts = (res[res.length - 1] || "").slice(0, index) || "";
  cur = (res[res.length - 1] || "")[index] || "";
  recureGrayCode(n, res, index + 1, `${tmp}${nexts!=="" ? (!(nexts ^ tmp) ? (cur !== "1" ? "1" : "0") : cur) : "1"}`);
};

思考

题目其实不是很难,只是需要绕点脑筋来做,懂得主动去制造规律,就方便很多了。


感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。

写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤