Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

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

Copy link
Copy link
Open
@grandyang

Description

@grandyang
Issue body actions

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 打赏


---|---

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.