1238. Circular Permutation in Binary Representation
SourceWeekly Contest 160 Q2DifficultyMediumRating1774
Description
Given 2 integers n and start. Your task is return any permutation p of (0,1,2.....,2^n -1) such that :
p[0] = startp[i]andp[i+1]differ by only one bit in their binary representation.p[0]andp[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 <= 160 <= start < 2 ^ n
Solutions
Solution 1: Binary Code to Gray Code
Thinking
Adjacent values (including the wrap-around) differ by one bit, which is a Gray code. \(i\oplus(i\gg 1)\) builds a Gray cycle on \(0\ldots 2^n-1\). \(n \le 16\) lets us list every codeword.
After generating the sequence we locate \(start\) and rotate so it comes first; circular adjacency is preserved.
We observe the arrangement in the problem, and find that in its binary representation, only one bit is different between any two (including the first and last) adjacent numbers. This kind of coding method is Gray code, which is a coding method we will encounter in engineering.
The rule for converting binary code to binary Gray code is to keep the highest bit of the binary code as the highest bit of the Gray code, and the second highest bit of the Gray code is the XOR of the highest bit and the second highest bit of the binary code. The rest of the Gray code is similar to the second highest bit.
Assume a binary number is represented as \(B_{n-1}B_{n-2}...B_2B_1B_0\), its Gray code representation is \(G_{n-1}G_{n-2}...G_2G_1G_0\). The highest bit is kept, so \(G_{n-1} = B_{n-1}\); and the other bits \(G_i = B_{i+1} \oplus B_{i}\), where \(i=0,1,2..,n-2\).
Therefore, for an integer \(x\), we can use the function \(gray(x)\) to get its Gray code:
int gray(x) {
return x ^ (x >> 1);
}
We can directly convert the integers \([0,..2^n - 1]\) into the corresponding Gray code array, then find the position of \(start\) in the Gray code array, cut the Gray code array from this position, and then append the cut part to the front of the Gray code array to get the arrangement required by the problem.
The time complexity is \(O(2^n)\), and the space complexity is \(O(2^n)\). Where \(n\) is the integer given in the problem.
1 2 3 4 5 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
1 2 3 4 5 6 7 8 9 10 11 | |
1 2 3 4 5 6 7 | |
Solution 2: Conversion Optimization
Thinking
Solution 1 generates then rotates. \(gray(i)\oplus start\) still differs by one bit between neighbors, and equals \(start\) at \(i=0\), so we map \(i\) directly and skip the search-and-concat step.
Since \(gray(0) = 0\), then \(gray(0) \oplus start = start\), and \(gray(i)\) is only one binary bit different from \(gray(i-1)\), so \(gray(i) \oplus start\) is also only one binary bit different from \(gray(i-1) \oplus start\).
Therefore, we can also directly convert the integers \([0,..2^n - 1]\) into the corresponding \(gray(i) \oplus start\) to get the Gray code arrangement with \(start\) as the first term.
The time complexity is \(O(2^n)\), where \(n\) is the integer given in the problem. Ignoring the space consumption of the answer, the space complexity is \(O(1)\).
1 2 3 | |
1 2 3 4 5 6 7 8 9 | |
1 2 3 4 5 6 7 8 9 10 | |
1 2 3 4 5 6 | |