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
确定解的个数而不是形式,把上述代码小改即可。