An n-bit gray code sequence is a sequence of 2n
integers where:
- Every integer is in the inclusive range
[0, 2n - 1]
, - The first integer is
0
, - An integer appears no more than once in the sequence,
- The binary representation of every pair of adjacent integers differs by exactly one bit, and
- The binary representation of the first and last integers differs by exactly one bit.
Given an integer n
, return any valid n-bit gray code sequence.
Example 1:
Input: n = 2 Output: [0,1,3,2] Explanation: The binary representation of [0,1,3,2] is [00,01,11,10]. - 00 and 01 differ by one bit - 01 and 11 differ by one bit - 11 and 10 differ by one bit - 10 and 00 differ by one bit [0,2,3,1] is also a valid gray code sequence, whose binary representation is [00,10,11,01]. - 00 and 10 differ by one bit - 10 and 11 differ by one bit - 11 and 01 differ by one bit - 01 and 00 differ by one bit
Example 2:
Input: n = 1 Output: [0,1]
Constraints:
1 <= n <= 16
这题前段时间遇到过一回,费了半天劲也没做出来,最后放弃了,结果今天又蹦出来了,赤裸裸的挑衅,办它。
思路:
这题在我看来就是纯粹的找规律的题, 拿出纸笔,写出一组答案,然后开始相面。
n = 3时答案为[0, 1, 3, 2, 6, 7, 5, 4], 转换成二进制就是[000, 001, 011, 010, 110, 111, 101, 100]。
端详了半天,一开始以为是用两层循环就好了,后来发现根本没法覆盖所有的数,于是继续找规律,最终在mask身上找到了突破口。我们每生成一个新的数字,就是在原有数字的基础上^(1 << k)得来, 这个1<<k就是mask,我们把所有用到的mask列出来:
变化 Mask left shift
000 -> 001: 001 0
001 -> 011: 010 1
011 -> 010: 001 0
010 -> 110: 100 2
110 -> 111: 001 0
111 -> 101: 010 1
101 -> 100: 001 0
貌似也没什么规律是不是, 一开始我认为是(0), (1, 0), (2, 0, 1),(3, 0, 1, 2), ......, (n, 0, 1, 2, ..., n-1), 这种规律, 后来实现的时候发现不对, 因为n=3的时候会缺少最后一个元素。后来又一想,有没有可能是遍历嵌套递归呢?试了一下, 通过了。
代码(Rust):
impl Solution {
fn rc(n: i32, num: &mut i32, l: &mut Vec<i32>) {
*num = *num ^ (1 << n);
l.push(*num);
for i in 0..n {
Solution::rc(i, num, l);
}
}
pub fn gray_code(n: i32) -> Vec<i32> {
let mut ans: Vec<i32> = vec![0];
let mut num = 0;
for i in 0..n {
Solution::rc(i, &mut num, &mut ans)
}
ans
}
}