一、Problem
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.
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]
Constraints:
1 <= n <= 16
0 <= start < 2 ^ n
二、Solution
方法一:回溯
这里要想到如何获得一个和上一个数字的二进制位只有一位不同的数字:int v = cur ^ (1 << j) (0 < j <n)
class Solution {
List<Integer> ans;
int tot, n;
boolean fl, vis[];
void dfs(int i, int cur) {
if (i == tot) {
fl = true;
return;
}
if (fl)
return;
ans.add(cur);
vis[cur] = true;
for (int j = 0; j < n; j++) { // 从低位到高位进行翻转,但本题没有顺序要求
int v = cur ^ (1 << j);
if (!vis[v])
dfs(i+1, v);
}
}
public List<Integer> circularPermutation(int n, int start) {
tot = 1 << n;
this.n = n;
vis = new boolean[tot+1];
ans = new LinkedList<>();
dfs(0, start);
return ans;
}
}
递归和迭代的写法思路是一样的:
for (int i = 1; i < tot; i++)
for (int j = 0; j < n; j++) {
...
}
复杂度分析
- 时间复杂度:,
- 空间复杂度:,
方法二:格雷码 + 旋转数组(代办)
参考了别人的思路,在这之前还不知道格雷码
复杂度分析
- 时间复杂度:,
- 空间复杂度:,