Solution 1
利用DFS,从0开始寻找满足要求的序列,由于找到就好,所以找到就直接返回,不需要回溯(主要是一定能找到这个性质比较有意思,不然的话实际上算法里是缺乏首尾元素验证的,这个我不太明白)。
- 时间复杂度: O ( n ⋅ 2 n ) O(n \cdot 2^n) O(n⋅2n),其中 n n n为输入,深度遍历
- 空间复杂度: O ( 2 n ) O(2^n) O(2n),其中 n n n为输入,结果输出占用
class Solution {
public:
vector<int> grayCode(int n) {
vector<int> ans;
vector<bool> used(1 << n, false);
this->dfs(n, used, 0, ans);
return ans;
}
private:
void dfs(int n, vector<bool>& used, int now, vector<int>& ans) {
if (!used[now]) {
used[now] = true;
ans.push_back(now);
}
for (int i = 0; i < n; ++i) {
int temp = now ^ (1 << i);
if (!used[temp]) {
this->dfs(n, used, temp, ans);
return;
}
}
}
};
Solution 2
下面是从网络上搜索的题解。
格雷码有很多有意思的性质:和二进制数的转换,以及镜面性质。
对于二进制数的转换,在维基百科上有介绍,假设两个序列都已0为起始,则有关系:
G ( n u m ) = n u m XOR ( n u m > > 1 ) G(num) = num \operatorname{XOR} (num >> 1) G(num)=numXOR(num>>1)
根据这个特性,从0开始逐渐转换计算就可以了
- 时间复杂度: O ( 2 n ) O(2^n) O(2n),其中 n n n为输入,线性遍历长度要求
- 空间复杂度: O ( 2 n ) O(2^n) O(2n),其中 n n n为输入,结果输出占用
class Solution {
public:
vector<int> grayCode(int n) {
vector<int> ans;
for (int i = 0; i < (1 << n); ++i) {
ans.push_back(i ^ (i >> 1));
}
return ans;
}
};
Solution 3
下面是从网络上搜索的题解。
镜面构造性质:设 n n n 阶格雷码集合为 G ( n ) G(n) G(n),则 n + 1 n+1 n+1阶格雷码为:
- 给 n n n 阶格雷码每个元素二进制形式前面添加 0,得到 G ′ ( n ) G^\prime(n) G′(n)
- 设 G ( n ) G(n) G(n)集合镜像为 R ( n ) R(n) R(n),给 R ( n ) R(n) R(n)每个元素二进制形式前面添加 1,得到 R ′ ( n ) R^\prime(n) R′(n)
- G ( n + 1 ) = G ′ ( n ) ∪ R ′ ( n ) G(n+1) = G'(n) ∪ R'(n) G(n+1)=G′(n)∪R′(n)即为 n + 1 n+1 n+1阶格雷码
- 时间复杂度: O ( 2 n ) O(2^n) O(2n),其中 n n n为输入,线性遍历长度要求, O ( 2 0 + 2 1 + … + 2 n − 1 ) = O ( 2 n ) O(2^0 + 2^1 + \ldots + 2^{n - 1}) = O(2^n) O(20+21+…+2n−1)=O(2n)
- 空间复杂度: O ( 2 n ) O(2^n) O(2n),其中 n n n为输入,结果输出占用
class Solution {
public:
vector<int> grayCode(int n) {
vector<int> ans;
ans.push_back(0);
for (int i = 0; i < n; ++i) {
// 镜面构造阶数
for (int j = ans.size() - 1; j >= 0; --j) {
// 镜面+补1
ans.push_back(ans[j] | (1 << i));
}
}
return ans;
}
};
Solution 4
Solution 1的Python实现
class Solution:
def grayCode(self, n: int) -> List[int]:
ans = list()
def dfs(now):
if not used[now]:
used[now] = True
ans.append(now)
for i in range(n):
temp = now ^ (1 << i)
if not used[temp]:
dfs(temp)
break
ans = list()
used = [False] * (1 << n)
dfs(0)
return ans
Solution 5
Solution 2的Python实现
class Solution:
def grayCode(self, n: int) -> List[int]:
ans = list()
for i in range (1 << n):
ans.append(i ^ (i >> 1))
return ans
Solution 5
Solution 3的Python实现
class Solution:
def grayCode(self, n: int) -> List[int]:
ans = list()
ans.append(0)
for i in range(n):
for j in range(len(ans) - 1, -1, -1):
ans.append(ans[j] | (1 << i))
return ans