Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LeetCode] 1238. Circular Permutation in Binary Representation #1238

Open
grandyang opened this issue May 30, 2019 · 0 comments
Open

[LeetCode] 1238. Circular Permutation in Binary Representation #1238

grandyang opened this issue May 30, 2019 · 0 comments

Comments

@grandyang
Copy link
Owner

grandyang commented May 30, 2019

Given 2 integers n and start. Your task is return any permutation p of (0,1,2.....,2^n -1) such that :

  • p[0] = start
  • p[i] and p[i+1] differ by only one bit in their binary representation.
  • p[0] and p[2^n -1] must also differ by only one bit in their binary representation.

Example 1:

Input: n = 2, start = 3
Output: [3,2,0,1]
Explanation: The binary representation of the permutation is (11,10,00,01).
All the adjacent element differ by one bit. Another valid permutation is [3,1,0,2]

Example 2:

Input: n = 3, start = 2
Output: [2,6,7,5,4,0,1,3]
Explanation: The binary representation of the permutation is (010,110,111,101,100,000,001,011).

Constraints:

  • 1 <= n <= 16
  • 0 <= start < 2 ^ n

这道题说是给了两个整数n和 start,让返回一个 [0, 2^n-1] 范围内的全排列,使得起始数字是 start,并且相邻的两个数字之间只能相差一位,注意末尾和开头的数字也只能相差一位。所谓相差一位的意思就是说其二进制数中只有一个 bit 的不同,比如 111 和 101 就是相差一位的。这种求二进制数之间相差一位的题目之前也遇到过,就是那道求格雷码的题目 Gray Code,这里稍微不同的是起始数字不再是0,而是给定的 start,但还是要输出n个数字。这道题的主要难点还是要理解格雷码 Gray Code,可以参见维基百科或是这个帖子,对于有序数列中的i,生成其对应的格雷码的公式是 i ^ (i>>1),这样求可以将 [0, 2^n-1] 范围内的对应的格雷码求出来了,如下表中的第三列所示:

Int Binary Gray Code ^011
0 000 000 011
1 001 001 010
2 010 011 000
3 011 010 001
4 100 110 101
5 101 111 100
6 110 101 110
7 111 100 111

但是这道题给定了一个起始数字,那怎么生成以 start 为起始的格雷码呢?其实只要让之前按顺序生成的格雷码同时 '亦或' 上这个 start,得到的新的序列还是格雷码,具体的证明博主也不会,但确实是对的,可以参见上表中的第四列,即将第三列的格雷码同时 '亦或' 上 011,得到的还是格雷码,知道如何证明的童鞋欢迎留言给博主,参见代码如下:

解法一:

class Solution {
public:
    vector<int> circularPermutation(int n, int start) {
        vector<int> res;
        for (int i = 0; i < (1 << n); ++i) {
            res.push_back(start ^ i ^ (i >> 1));
        }
        return res;
    }
};

如果无法想到同时 '亦或' 上 start 这个操作,那么也可以采用笨办法,直接旋转按顺序生成的格雷码,找到其中的 start 位置,将其旋转到起始位置即可,因为相对位置不变,所以还是格雷码,参见代码如下:

解法二:

class Solution {
public:
    vector<int> circularPermutation(int n, int start) {
        vector<int> res;
        for (int i = 0; i < (1 << n); ++i) {
            res.push_back(i ^ (i >> 1));
        }
        rotate(res.begin(), find(res.begin(), res.end(), start), res.end());
        return res;
    }
};

Github 同步地址:

#1238

类似题目:

Gray Code

参考资料:

https://leetcode.com/problems/circular-permutation-in-binary-representation/

https://leetcode.com/problems/circular-permutation-in-binary-representation/discuss/469592/C%2B%2B-6-line-intuitive-DP-solution

https://leetcode.com/problems/circular-permutation-in-binary-representation/discuss/414203/JavaC%2B%2BPython-4-line-Gray-Code

LeetCode All in One 题目讲解汇总(持续更新中...)

喜欢请点赞,疼爱请打赏❤️~.~

微信打赏

|

Venmo 打赏


---|---

@grandyang grandyang changed the title [LeetCode] 1238. Missing Problem Nov 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
1 participant