思路
题目要求给出任意一种全排列数组。我们可以设计一种算法,每次改变一个比特位,从而生成一个新的数。
这个具体的生成算法就是,从最后一位尝试改变,如果改变后的数之前遍历到了,则撤回改变,并尝试下一个数。而其中判决生成的数之前是否已经遍历过了,需要一个 HashMap 记录,这里我们直接用 count 数组记录就行。
public int next(int a, int[] count) {
int xor = 1;
while (true) {
a ^= xor;
if (count[a] == 0) {
count[a]=1;
return a;
}
a ^= xor;
xor <<= 1;
}
}
这样不断生成新的数,可以保证新数和前面的数只差一个比特位。也不难想到为什么最后一个数必须和第一个数相隔一位(因为如果排除掉第一个数 start,再生成一个新数必然是 start, 不然就和前面的数重复了)。
于是,整个代码如下:
class Solution {
public List<Integer> circularPermutation(int n, int start) {
int[] count = new int[(int) Math.pow(2, n)];
List<Integer> res = new ArrayList<>(count.length);
res.add(start);
count[start] = 1;
for (int i = 1; i < count.length; i++) {
start = next(start, count);
res.add(start);
}
return res;
}
public int next(int a, int[] count) {
int xor = 1;
while (true) {
a ^= xor;
if (count[a] == 0) {
count[a]=1;
return a;
}
a ^= xor;
xor <<= 1;
}
}