89. Gray Code
题目描述
The gray code is a binary numeral system where two successive values differ in only one bit.
Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0.
For example, given n = 2, return [0,1,3,2]. Its gray code sequence is:
00 - 0
01 - 1
11 - 3
10 - 2
Note:
For a given n, a gray code sequence is not uniquely defined.
For example, [0,2,3,1] is also a valid gray code sequence according to the above definition.
For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that.
Subscribe to see which companies asked this question.
解题思路
法一:把格雷码写出来,然后可以发现一个规律,就是第一位是0110重复,第二位是00111100,第三位是0000111111110000,第四位是00000000111111111111111100000000. 所以代码可以写成:
class Solution {
public:
vector<int> grayCode(int n) {
vector<int> res;
int num = 1 << n;
int tmp = 0;
for(int i = 0; i < num; i++) {
tmp = 0;
for(int j = 1; j <= n; j++) {
int divend = 1 << (j+1);
int rem = i%divend;
tmp += (rem >= (1 << (j-1)) && rem < ((1 << (j-1))*3)) << (j - 1);
// cout << (rem >= (1 << (j-1)) && rem < ((1 << (j-1))*3)) << (j - 1) << " " << i << " rem" << rem << "div" << divend<< endl;
}
res.push_back(tmp);
}
return res;
}
};
另外根据wiki上格雷码的定义,可以知道:
class Solution {
public:
vector<int> grayCode(int n) {
int num = 1 << n;
vector<int> res;
for (int i=0; i < num; i++)
res.push_back(i^(i>>1));
return res;
}
};
但是这样的思路让人觉得不够自动化,还需要人去总结这些东西。
在discussion部分有人提供了这个比较特别的思路。我觉得这个不能算作是回溯。普通的递归吧。
https://discuss.leetcode.com/topic/31750/backtracking-c-solution
class Solution {
void utils(bitset<32>& bits, vector<int>& result, int k){
if (k==0) {
result.push_back(bits.to_ulong());
}
else {
utils(bits, result, k-1);
bits.flip(k-1);
utils(bits, result, k-1);
}
}
public:
vector<int> grayCode(int n) {
bitset<32> bits;
vector<int> result;
utils(bits, result, n);
return result;
}
};
51. N-Queens
题目描述
Given an integer n, return all distinct solutions to the n-queens puzzle.
Each solution contains a distinct board configuration of the n-queens’ placement, where ‘Q’ and ‘.’ both indicate a queen and an empty space respectively.
For example,
There exist two distinct solutions to the 4-queens puzzle:
[
[".Q..", // Solution 1
"...Q",
"Q...",
"..Q."],
["..Q.", // Solution 2
"Q...",
"...Q",
".Q.."]
]
代码实现
这里我用数字0和1表示棋盘,然后再换成字母,好像没有必要这么做。
class Solution {
public:
void putIntoAnswer(vector<vector<string> > &res, vector<vector<int> > &chess, int n) {
vector<string> vs;
for(int i = 0; i < n; i++) {
string tmp;
for(int j = 0; j < n; j++) {
tmp += (chess[i][j]?'Q':'.');
}
vs.push_back(tmp);
}
res.push_back(vs);
}
bool isSatisfyRule(vector<vector<int> > chess, int n, int stt) {
for(int i = 0; i <= stt; i++)
for(int j = 0; j < n; j++) {
if(chess[i][j] == 1) {
int row = i, col = j;
while((--col) >= 0 && (++row) <= stt) {
if(chess[row][col] == 1)
return false;
}
row = i, col = j;
while((++row) <= stt) {
if(chess[row][col] == 1)
return false;
}
row = i, col = j;
while((++row) <= stt && (++col) < n) {
if(chess[row][col] == 1)
return false;
}
}
}
return true;
}
void nQueen(vector<vector<string> > &res, vector<vector<int> > &chess, int n, int stt) {
if(stt == n) { // isSolution(chess, stt, n)) {
putIntoAnswer(res, chess, n);
return;
}
if(stt == n)
return;
// the number stt stands for the row
// i stands for column.
for(int i = 0; i < n; i++) {
chess[stt][i] = 1;
if(isSatisfyRule(chess, n, stt))
nQueen(res, chess, n, stt+1);
chess[stt][i] = 0;
}
}
vector<vector<string>> solveNQueens(int n) {
vector<vector<string> > res;
vector<vector<int>> chess(n, vector<int>(n, 0));
nQueen(res, chess, n, 0);
return res;
}
};
修改了一下代码,使得速度提升了一些,都是还不够快。
class Solution {
public:
void putIntoAnswer(vector<vector<string> > &res, vector<vector<char> > &chess, int n) {
vector<string> vs;
for(int i = 0; i < n; i++) {
string tmp(chess[i].begin(), chess[i].end());
/*
for(int j = 0; j < n; j++) {
tmp += chess[i][j];
}
*/
vs.push_back(tmp);
}
res.push_back(vs);
}
bool isSatisfyRule(vector<vector<char> > chess, int n, int stt) {
for(int i = 0; i <= stt; i++)
for(int j = 0; j < n; j++) {
if(chess[i][j] == 'Q') {
int row = i, col = j;
while((--col) >= 0 && (++row) <= stt) {
if(chess[row][col] == 'Q')
return false;
}
row = i, col = j;
while((++row) <= stt) {
if(chess[row][col] == 'Q')
return false;
}
row = i, col = j;
while((++row) <= stt && (++col) < n) {
if(chess[row][col] == 'Q')
return false;
}
}
}
return true;
}
void nQueen(vector<vector<string> > &res, vector<vector<char> > &chess, int n, int stt) {
if(stt == n) { // isSolution(chess, stt, n)) {
putIntoAnswer(res, chess, n);
return;
}
// the number stt stands for the row
// i stands for column.
for(int i = 0; i < n; i++) {
chess[stt][i] = 'Q';
if(isSatisfyRule(chess, n, stt))
nQueen(res, chess, n, stt+1);
chess[stt][i] = '.';
}
}
vector<vector<string>> solveNQueens(int n) {
vector<vector<string> > res;
vector<vector<char>> chess(n, vector<char>(n, '.'));
nQueen(res, chess, n, 0);
return res;
}
};
再修改:
class Solution {
public:
void putIntoAnswer(vector<vector<string> > &res, vector<vector<char> > &chess, int n) {
vector<string> vs;
for(auto i:chess) {
vs.push_back(string(i.begin(), i.end()));
}
res.push_back(vs);
}
bool isSatisfyRule(vector<vector<char> > chess, int n, int stt) {
for(int i = 0; i <= stt; i++)
for(int j = 0; j < n; j++) {
if(chess[i][j] == 'Q') {
int row = i, col = j;
while((--col) >= 0 && (++row) <= stt) {
if(chess[row][col] == 'Q')
return false;
}
row = i, col = j;
while((++row) <= stt) {
if(chess[row][col] == 'Q')
return false;
}
row = i, col = j;
while((++row) <= stt && (++col) < n) {
if(chess[row][col] == 'Q')
return false;
}
}
}
return true;
}
void nQueen(vector<vector<string> > &res, vector<vector<char> > &chess, int n, int stt) {
if(stt == n) { // isSolution(chess, stt, n)) {
putIntoAnswer(res, chess, n);
return;
}
// the number stt stands for the row
// i stands for column.
for(int i = 0; i < n; i++) {
chess[stt][i] = 'Q';
if(isSatisfyRule(chess, n, stt))
nQueen(res, chess, n, stt+1);
chess[stt][i] = '.';
}
}
vector<vector<string>> solveNQueens(int n) {
vector<vector<string> > res;
vector<vector<char>> chess(n, vector<char>(n, '.'));
nQueen(res, chess, n, 0);
return res;
}
};
52. N-Queens II
题目描述
Follow up for N-Queens problem.
Now, instead outputting board configurations, return the total number of distinct solutions.
代码实现
把上面n 皇后的问题改一下就可以了。
class Solution {
public:
bool isSatisfyWithRule(vector<vector<int>>chess, int n, int stt) {
for(int i = 0; i <= stt; i++) {
for(int j = 0; j < n; j++) {
if(chess[i][j]) {
int row = i, col = j;
while((++row) <= stt && (--col) >= 0)
if(chess[row][col])
return false;
row = i, col = j;
while((++row) <= stt )
if(chess[row][col])
return false;
row = i ,col = j;
while((++row) <= stt && (++col) < n)
if(chess[row][col])
return false;
}
}
}
// cout << n << " " << stt << endl;
return true;
}
void bp(int &res, vector<vector<int>>&chess, int stt, int n) {
if(stt == n) {
res++;
// cout << res << endl;
return;
}
for(int i = 0; i < n; i++) {
chess[stt][i] = 1;
if(isSatisfyWithRule(chess, n, stt))
bp(res, chess, stt+1, n);
chess[stt][i] = 0;
}
}
int totalNQueens(int n) {
int res = 0;
vector<vector<int>>chess(n, vector<int>(n, 0));
bp(res, chess, 0, n);
return res;
}
};