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) {
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
|