401. Binary Watch && 51. N-Queens

401. Binary Watch(回溯法基本应用)

A binary watch has 4 LEDs on the top which represent the hours (0-11), and the 6 LEDs on the bottom represent the minutes (0-59).

Each LED represents a zero or one, with the least significant bit on the right.



For example, the above binary watch reads “3:25”.

Given a non-negative integer n which represents the number of LEDs that are currently on, return all possible times the watch could represent.

Example:

Input: n = 1
Return: ["1:00", "2:00", "4:00", "8:00", "0:01", "0:02", "0:04", "0:08", "0:16", "0:32"]

Note:

  • The order of output does not matter.
  • The hour must not contain a leading zero, for example “01:00” is not valid, it should be “1:00”.
  • The minute must be consist of two digits and may contain a leading zero, for example “10:2” is not valid, it should be “10:02”.
解题思路

这道题显然需要穷举所有可能的情况,也就是求排列/组合的问题,采用回溯法解决。

回溯法一般情况下,格式如下:

backtrack(visit, num):
    if num == 0: get one result
    else for all element:
        if visit[element] == 0:
            visit[element] = 1
            backtrack(visit, num - 1)
            visit[element] = 0

对于这道题,只需遍历所有可能的位置回溯即可。

程序代码
class Solution {
public:
    void addTime(vector<bool>& leds, vector<string>& times){
        int hour = 8 * leds[0] + 4 * leds[1] + 2 * leds[2] + leds[3];
        int minute = 32 * leds[4] + 16 * leds[5] + 8 * leds[6] + 4 * leds[7] + 2 * leds[8] + leds[9];
        if (hour < 12 && minute < 60){
            stringstream s;
            s << hour << (minute >= 10? ":" : ":0") << minute;
            times.push_back(s.str());
        }
    }

    void getAllTimes(vector<bool>& leds, vector<string>& times, int num, int pos){
        if (num == 0) addTime(leds, times);
        else for(int i = pos; i < 10; i++){
            leds[i] = 1;
            getAllTimes(leds, times, num - 1, i + 1);
            leds[i] = 0;
        }
    }

    vector<string> readBinaryWatch(int num) {
        vector<bool> leds(10, 0);
        vector<string> times;
        getAllTimes(leds, times, num, 0);
        return times;
    }
};

51. N-Queens(回溯法应用)

The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.



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.

Example:

Input: 4
Output: [
 [".Q..",  // Solution 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // Solution 2
  "Q...",
  "...Q",
  ".Q.."]
]
Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above.
解题思路

同样地,需要遍历所有的情况,同时在回溯法的基础上判断是否满足条件,关键在于如何快速的判断。

使用N*N矩阵,每次遍历所有位置判断,效率较低,此处采用下列判断方法:

  • 使用一个向量colOfRows表示每一行放置queen的列,每次循环用于确定当前行的放置位置(第一次确定第一行的位置,第二次确定第二行的位置,而不用每次在N*N矩阵中找一个可放置的位置)
  • 判断是否可行时,只需判断列是否有重复和对角线是否冲突即可
程序代码
class Solution {
public:
    vector<vector<string>> solveNQueens(int n) {
        vector<string> box(n, string(n, '.'));
        vector<vector<string>> solutions;
        vector<int> colOfRows(n,-1); //记录每一行的queen放置的列
        getAllSolu(box, solutions, colOfRows, n, 0);
        return solutions;
    }
    void getAllSolu(vector<string>& box, vector<vector<string>>&solutions, vector<int>& colOfRows, int n, int row){
        cout<<n;
        if (n == 0) solutions.push_back(box);
        else for (int i = 0; i < box.size(); i++){
            colOfRows[row] = i;
            if (isValid(colOfRows, row)){
                box[row][i] = 'Q';
                getAllSolu(box, solutions, colOfRows, n - 1, row + 1);
                box[row][i] = '.';
            }
        }
    }
    bool isValid(vector<int>& colOfRows, int row){
        //行必不相同,只需比较列和对角线
        for (int i = 0; i < row; i++)
            if (colOfRows[i] == colOfRows[row] || abs(i - row) == abs(colOfRows[i] - colOfRows[row]))
                return 0;
        return 1;
    }
};

52. N-QueensII

确定解的个数而不是形式,把上述代码小改即可。

猜你喜欢

转载自blog.csdn.net/qq_36153312/article/details/81982102