递增子序列
class Solution {
public:
vector<int> path;
vector<vector<int>> result;
void backtracking(vector<int>& nums, int index){
if(path.size() > 1){
result.push_back(path);
}
unordered_set<int> used;
for(int i = index; i < nums.size(); i++){
if((path.empty() || nums[i] >= path.back()) && used.find(nums[i]) == used.end()){
used.insert(nums[i]);
path.push_back(nums[i]);
backtracking(nums, i+1);
path.pop_back();
}
}
}
vector<vector<int>> findSubsequences(vector<int>& nums) {
result.clear();
path.clear();
backtracking(nums, 0);
return result;
}
};
全排列
class Solution {
public:
vector<int> path;
vector<vector<int>> result;
vector<vector<int>> permute(vector<int>& nums) {
unordered_set<int> used;
backtracking(nums, used);
return result;
}
void backtracking(vector<int>& nums, unordered_set<int> &used){
if(path.size() == nums.size()){
result.push_back(path);
return;
}
for(int i = 0; i < nums.size(); i++){
if(used.find(nums[i]) == used.end()){
used.insert(nums[i]);
path.push_back(nums[i]);
backtracking(nums, used);
used.erase(nums[i]);
path.pop_back();
}
}
}
};
全排列 II
class Solution {
public:
vector<int> path;
vector<vector<int>> result;
vector<vector<int>> permuteUnique(vector<int>& nums) {
// sort(nums.begin(), nums.end());
vector<bool> used(nums.size(), false);
backtracking(nums, used);
return result;
}
void backtracking(vector<int>& nums, vector<bool> &used){
if(path.size() == nums.size()){
result.push_back(path);
return;
}
unordered_set<int> uset;//树层
for(int i = 0; i < nums.size(); i++){
if(!used[i] && uset.find(nums[i]) == uset.end()){
uset.insert(nums[i]);
path.push_back(nums[i]);
used[i] = true;
backtracking(nums, used);
used[i] = false;
path.pop_back();
}
}
}
};
树层去重用一个不进入回溯的set去存当前位置使用过的数
重新安排行程
//会超时,
class Solution {
public:
vector<string> path;
vector<string> result;
vector<string> findItinerary(vector<vector<string>>& tickets) {
result.clear();
result.clear();
path.push_back("JFK");
sort(tickets.begin(), tickets.end(), [](vector<string>& a, vector<string>& b){
if(a[0] == b[0]){
return a[1] < b[1];
}
return a[0] < b[0];
});
vector<bool> used(tickets.size(), false);
backtracking(tickets, used, "JFK");
return result;
}
bool backtracking(vector<vector<string>>& tickets, vector<bool>& used, string startIndex){
if(path.size() == tickets.size() + 1){
result = path;
return true;
}
for(int i = 0; i < tickets.size(); i++){
if(used[i] || tickets[i][0] != startIndex){
continue;
}
used[i] = true;
path.push_back(tickets[i][1]);
bool res = backtracking(tickets, used, tickets[i][1]);
if(res)
return true;
used[i] = false;
path.pop_back();
}
}
};
class Solution {
public:
vector<string> result;
unordered_map<string, map<string, int>> targets;
vector<string> findItinerary(vector<vector<string>>& tickets) {
result.push_back("JFK");
for(int i = 0; i < tickets.size(); i++){
targets[tickets[i][0]][tickets[i][1]]++;
}
backtracking(tickets, "JFK");
return result;
}
bool backtracking(vector<vector<string>>& tickets, string starting){
if(result.size() == tickets.size() + 1){
// 已经排过序,找到的第一组就是更小的
return true;
}
// pair<const string, int> &m : targets[starting]
for(pair<const string, int> &m : targets[starting]){
// m.first终点 m.second起点到终点的航班数
if(m.second > 0){
m.second--;
result.push_back(m.first);
if(backtracking(tickets, m.first))
return true;
result.pop_back();
m.second++;
}
}
return false;
}
};
N皇后
class Solution {
public:
vector<vector<string>> result;
vector<int> row;
vector<int> col;
vector<int> obl1;
vector<int> obl2;
vector<vector<string>> solveNQueens(int n) {
vector<string> board(n, string(n, '.'));
row = vector<int>(n, 0);
col = vector<int>(n, 0);
obl1 = vector<int>(2*n-1, 0);
obl2 = vector<int>(2*n-1, 0);
backtracking(n, board, 0);
return result;
}
// 需要加一个行或列的参数进入回溯,避免重复的结果
void backtracking(int n, vector<string>& board, int y){
if(n == 0){
result.push_back(board);
return;
}
for(int i = y; i < board.size(); i++){
if(row[i] != 0)
continue;
for(int j = 0; j < board.size(); j++){
if(col[j] != 0)
continue;
if(obl1[i-j + board.size()-1] == 0 && obl2[i+j] == 0){
board[i][j] = 'Q';
row[i]++;
col[j]++;
obl1[i-j + board.size()-1]++;
obl2[i+j]++;
backtracking(n-1, board, i+1);
board[i][j] = '.';
row[i]--;
col[j]--;
obl1[i-j + board.size()-1]--;
obl2[i+j]--;
}
}
}
}
};
解数独
class Solution {
public:
string str = "123456789";
void solveSudoku(vector<vector<char>>& board) {
backtracking(board);
}
bool isValid(vector<vector<char>>& board, int y, int x, char ch){
for(int i = 0; i < 9; i++){
if(board[y][i] == ch || board[i][x] == ch)
return false;
}
for(int i = (y/3)*3; i < (y/3)*3+3; i++){
for(int j = (x/3)*3; j < (x/3)*3 + 3; j++){
if(board[i][j] == ch)
return false;
}
}
return true;
}
bool backtracking(vector<vector<char>>& board){
for(int i = 0; i < 9; i++){
for(int j = 0; j < 9; j++){
if(board[i][j] == '.'){
for(char ch : str){
if(isValid(board, i, j, ch)){
board[i][j] = ch;
if(backtracking(board))
return true;
board[i][j] = '.';
}
}
return false;//错误解
}
}
}
return true;
}
};