题意理解
给定一个整数,求出一个满足格雷编码的序列,序列长度2^(n-1)
问题分析
用回溯,剪枝。
卡点有3个:1.是怎么对某一位取反。答案是异或+左移;2.怎么用回溯,保存一个当前结果的序列vector,当前序列和结果序列分开;3.怎么剪枝,当得到正确答案,直接跳出循环。设置一个flag标志位。
其他
这题做了一天。回溯是我的弱项,还是有些点有点卡,不过下次更好的。
链接
class Solution {
public:
vector<int> grayCode(int n) {
unordered_set<int> my_dict;
my_dict.insert(0);
vector<int> cur_res;
cur_res.push_back(0);
vector<int> res;
res.push_back(0);
int a = 0;
int flag = 0;
helper(a, n, my_dict, cur_res, res, flag);
return res;
}
void helper(int a, int n, unordered_set<int>& my_dict, vector<int>& cur_res, vector<int>& res,int& flag) {
//cout << "-- a:" << a << '\t' << "-- n:" << n << endl;
// for(auto a : cur_res) {
// cout << "cur_res:" << a << '\t';
// }
// cout << endl;
//终止条件
if (cur_res.size() == pow(2, n)) {
flag = 1;
res = cur_res;
return;
}
//递归条件
for(int i = 0; i < n; i ++) {
int a1 = a ^ (1 << i);
//cout << "a1: " << a1 << '\t' << "i: " << i << endl;
if (my_dict.count(a1)) {
//cout << "stop" << endl;
continue;
}
else {
my_dict.insert(a1);
a = a1;
cur_res.push_back(a1);
helper(a1, n, my_dict, cur_res, res, flag);
if (flag == 1) break;
my_dict.erase(a1);
cur_res.pop_back();
}
}
}
};