搜索和回溯(来源于Leetcode书籍)
1、46全排列
class Solution {
private:
int n;
unordered_map<int, bool> hashTable;
vector<int> nums, temp;
vector<vector<int>> res;
public:
vector<vector<int>> permute(vector<int>& nums) {
this->n = nums.size();
this->nums = nums;
for (int num : nums) hashTable[num] = false;
DFS(0);
return res;
}
void DFS(int index){
if (index == n){
res.push_back(temp);
return ;
}
for (int num : nums){
if (!hashTable[num]){
temp.push_back(num);
hashTable[num] = true;
DFS(index+1);
//状态恢复
temp.pop_back();
hashTable[num] = false;
}
}
}
};
2、36有效地数独
class Solution {
public:
bool isValidSudoku(vector<vector<char>>& board) {
int row[9][10], col[9][10], mat[3][3][10];
memset(row, 0, sizeof row);
memset(col, 0, sizeof col);
memset(mat, 0, sizeof mat);
int n = board.size(), m = board[0].size();
for (int i = 0; i < n; i++){
for (int j = 0; j < m; j++){
if (board[i][j] == '.') continue;
int index = board[i][j] - '0';
row[i][index]++;
col[j][index]++;
mat[i/3][j/3][index]++;
if (row[i][index] > 1 || col[j][index] > 1 || mat[i/3][j/3][index] > 1)
return false;
}
}
return true;
}
};
3、37解数独
class Solution {
private:
int n, m;
int row[9][10], col[9][10], mat[3][3][10];
public:
void solveSudoku(vector<vector<char>>& board) {
this->n = board.size(), this->m = board[0].size();
for (int i = 0; i < n; i++){
for (int j = 0; j < m; j++){
if (board[i][j] == '.') continue;
int index = board[i][j] - '0';
row[i][index]++;
col[j][index]++;
mat[i/3][j/3][index]++;
}
}
DFS(board, 0, 0);
}
bool DFS(vector<vector<char>> &board, int x, int y){
if (y == m) x++, y = 0;
if (x == n) return true;
if (board[x][y] != '.')
return DFS(board, x, y+1);
for (int i = 1; i <= 9; i++){
if (row[x][i] == 0 && col[y][i] == 0 && mat[x/3][y/3][i] == 0){
board[x][y] = i+'0';
row[x][i] = col[y][i] = mat[x/3][y/3][i] = 1;
if (DFS(board, x, y+1)) return true;
board[x][y] = '.';
row[x][i] = col[y][i] = mat[x/3][y/3][i] = 0;
}
}
return false;
}
};
4、22括号生成
class Solution {
private:
int n;
vector<string> res;
public:
vector<string> generateParenthesis(int n) {
this->n = n;
DFS("(", 1, 0);
return res;
}
void DFS(string str, int left, int right){
if (left == n){
//所有的左括号已经用完,那么这个括号就可以唯一确定
while(right < n){
str += ")";
right++;
}
res.push_back(str);
return ;
}else if (left > n)
return ;
DFS(str + "(", left+1, right);
if (left > right)
DFS(str + ")", left, right+1);
}
};
class Solution {
private:
int n;
string digits;
string strs[10] = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
vector<char> temp;
vector<string> res;
public:
vector<string> letterCombinations(string digits) {
this->n = digits.size();
if (n == 0) return res;
this->digits = digits;
DFS(0);
return res;
}
void DFS(int index){
if (index == n){
string str = "";
for (char ch : temp) str += ch;
res.push_back(str);
return;
}
int idx = digits[index]-'0';
for (int i = 0; i < strs[idx].size(); i++){
temp.push_back(strs[idx][i]);
DFS(index+1);
temp.pop_back();
}
}
};