89. Gray Code \ 51. N-Queens \ 52. N-Queens II

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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值