day13回溯3

90.子集II

class Solution {
public:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& nums, int startIndex, vector<bool>& used){
        result.push_back(path);// 收集子集,要放在终止添加的上面,否则会漏掉自己
       // if(startIndex >= nums.size()) return;
        for(int i=startIndex; i<nums.size(); i++){
            if(i>0 && nums[i]==nums[i-1] && used[i-1]==false) continue;
            path.push_back(nums[i]);
            used[i]=true;
            backtracking(nums,i+1,used);
            path.pop_back();
            used[i]=false;
        }
    }
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        result.clear();
        path.clear();
        vector<bool> used(nums.size(),false);
        sort(nums.begin(),nums.end());
        backtracking(nums, 0, used);
        return result;
    }
};

491.递增子序列

class Solution {
public:
vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& nums, int startIndex){
        if(path.size()>1)
            result.push_back(path);// 收集子集,要放在终止添加的上面,否则会漏掉自己
        unordered_set<int> uset;
        for(int i=startIndex; i<nums.size(); i++){
            if((!path.empty() && nums[i]<path.back()) || uset.find(nums[i]) != uset.end() ) 
                continue;
            uset.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();
        //vector<bool> used(nums.size(),false);
        backtracking(nums, 0);
        return result;
    }
};

此种解答 有问题,
前面的几题,自己不强调顺序,因此可以对原数组排序后采用used数组,而递增子序列需要保证原数组顺序,不可对原数组进行排序,因此nums[i]==nums[i-1]这个条件不适用,像4 7 6 7,nums[i]==nums[i-1] 对 7 和 6 不适用。
遗失的美好:
nums[i] 需要 不等于 前面所有的num[0]~nums[i-1]

class Solution {
public:
vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& nums, int startIndex, vector<bool>& used){
        if(path.size()>1)
            result.push_back(path);
        for(int i=startIndex; i<nums.size(); i++){
            if((!path.empty() && nums[i]<path.back()) || (i>0 && nums[i]==nums[i-1] && used[i-1]==false)) 
                continue;
            path.push_back(nums[i]);
            used[i]=true;
            backtracking(nums,i+1,used);
            path.pop_back();
            used[i]=false;
        }
    }
    vector<vector<int>> findSubsequences(vector<int>& nums) {
        result.clear();
        path.clear();
        vector<bool> used(nums.size(),false);
        backtracking(nums, 0, used);
        return result;
    }
};

可以写一个 for循环 然后判断一下?不行,1个continue 不能连跳 两个循环

if((!path.empty() && nums[i]<path.back()) || (i>0 && nums[i]==nums[i-1] && used[i-1]==false)) 
                continue;

改为:

 if(!path.empty() && nums[i]<path.back()) continue;
 for(int j=0;j<i;j++){
 	if(i>0 && nums[i]==nums[j] && used[j]==false)
         continue;
    }

还是不行,只能用set

46.全排列

class Solution {
public:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& nums, vector<bool>& used) {
        
        if (path.size() == nums.size()) {
            result.push_back(path);
            return;
        }
    
        for (int i = 0; i < nums.size(); i++) {
            if(used[i] == true) continue;
            used[i]=true;
            path.push_back(nums[i]);
            backtracking(nums, used);
            path.pop_back();
            used[i]=false;
        }
    }
    vector<vector<int>> permute(vector<int>& nums) {
        result.clear();
        path.clear();
        vector<bool> used(nums.size(),false);
        backtracking(nums, used);
        return result;
    }
};

47.全排列 II

class Solution {
public:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& nums, vector<bool>& used) {
        
        if (path.size() == nums.size()) {
            result.push_back(path);
            return;
        }
        for (int i = 0; i < nums.size(); i++) {
            if(used[i] == true) continue;
            if(i>0 && nums[i]==nums[i-1] && used[i-1]==false) continue;
            used[i]=true;
            path.push_back(nums[i]);
            backtracking(nums, used);
            path.pop_back();
            used[i]=false;
        }
    }
    vector<vector<int>> permuteUnique(vector<int>& nums) {
         result.clear();
        path.clear();
        vector<bool> used(nums.size(),false);
        sort(nums.begin(),nums.end());
        backtracking(nums, used);
        return result;
    }
};

332. 重新安排行程

还是有一点问题,没找到 问题在哪,超时了,有一个用例通过不了。

class Solution {
private:
    vector<string> path={"JFK"};
    vector<string> res;
    void backtracking(vector<vector<string>>& tickets,string from,vector<int>& used){
        if(used.back()==tickets.size()){
            res=path;
            return;
        }
        for(int i=0;i<tickets.size();i++){
            if(tickets[i][0]==from&&used[i]==0){
                used[i]=1;
                used[tickets.size()]+=1;
                path.push_back(tickets[i][1]);
                backtracking(tickets,tickets[i][1],used);
                path.pop_back();
                used[i]=0;
                used[tickets.size()]-=1;
            }
            if(res.size()){
                return;
            }
        }
    }
    
public:
    static bool combine(const vector<string>& a,const vector<string>& b){
        return a[1]<b[1];
    }
    vector<string> findItinerary(vector<vector<string>>& tickets) {
        sort(tickets.begin(),tickets.end(),combine);
        vector<int> used(tickets.size()+1,0);
        backtracking(tickets,"JFK",used);
        return res;
    }
};
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

class Solution {
public:
vector<string> findItinerary(vector<vector<string>>& tickets) {
  sort(tickets.begin(), tickets.end(), [](const vector<string>& a, const vector<string>& b) {
  return a[1] < b[1];
});
path.emplace_back("JFK");
vector<bool> used(tickets.size(), false);
backTracking(tickets, used);
return result;
}
bool backTracking(vector<vector<string>>& tickets, vector<bool>& used) {
  if (path.size() == tickets.size() + 1) {
  result = path;
  return true;
  }
  for (int i = 0; i < tickets.size(); i++) {
  if (!used[i] && tickets[i].front() == path.back()) {
  path.push_back(tickets[i][1]);
  used[i] = true;
  if (backTracking(tickets, used)) {
  return true;
}
used[i] = false;
path.pop_back();
}
}
return false;
}

private:
vector<string> result;
vector<string> path;
};

// int main() {
// Solution solution;
// vector<vector<string>> tickets = {{"MUC", "LHR"}, {"JFK", "MUC"}, {"SFO", "SJC"}, {"LHR", "SFO"}};
// vector<string> itinerary = solution.findItinerary(tickets);
// for (const string& city : itinerary) {
// cout << city << " ";
// }
// cout << endl;
// return 0;
// }

51. N皇后

class Solution {
public:
/*验证棋盘是否合法
按照如下标准去重:

不能同行
不能同列
不能同斜线 (45度和135度角)*/
bool isValid(int row, int col, vector<string>& chessboard, int n) {
    // 检查列   保证 同一列没有  同一行 是自己加上去的,一定没有皇后
    for (int i = 0; i < row; i++) { // 这是一个剪枝
        if (chessboard[i][col] == 'Q') {
            return false;
        }
    }
    // 检查 45度角是否有皇后
    for (int i = row - 1, j = col - 1; i >=0 && j >= 0; i--, j--) {
        if (chessboard[i][j] == 'Q') {
            return false;
        }
    }
    // 检查 135度角是否有皇后
    for(int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {
        if (chessboard[i][j] == 'Q') {
            return false;
        }
    }
    return true;
}
    vector<vector<string>> result;
    // n 为输入的棋盘大小
    // row 是当前递归到棋盘的第几行了
    void backtracking(int n,int row,vector<string>& chessboard){
        if(row==n){
            result.push_back(chessboard);
            return;
        }
        for(int i=0;i<n;i++){
            if(isValid(row,i,chessboard,n)){
                chessboard[row][i]='Q';
                backtracking(n,row+1,chessboard);
                chessboard[row][i]='.';
            }
        }
    }
    vector<vector<string>> solveNQueens(int n) {
        result.clear();
        std::vector<std::string> chessboard(n, std::string(n, '.'));
        /*创建一个n*n的棋盘,vector表示一个动态数组,
        string表示一个字符串,string初始化为一个由n个‘.’组成的字符串,
        然后这个字符串复制n次,,得到了n行n列的棋盘。*/
        backtracking(n, 0, chessboard);
        return result;
    }
};

37. 解数独

class Solution {
public:
bool isValid(int row, int col, char val, vector<vector<char>>& board) {
    for (int i = 0; i < 9; i++) { // 判断行里是否重复
        if (board[row][i] == val) {
            return false;
        }
    }
    for (int j = 0; j < 9; j++) { // 判断列里是否重复
        if (board[j][col] == val) {
            return false;
        }
    }
    int startRow = (row / 3) * 3;
    int startCol = (col / 3) * 3;
    for (int i = startRow; i < startRow + 3; i++) { // 判断9方格里是否重复
        for (int j = startCol; j < startCol + 3; j++) {
            if (board[i][j] == val ) {
                return false;
            }
        }
    }
    return true;
}
     bool backtracking(vector<vector<char>>& board){
        for(int i = 0; i < board.size(); i++){// 遍历行
            for (int j = 0; j < board[0].size(); j++) { // 遍历列
                if(board[i][j] == '.'){
                    for(char k='1';k<='9';k++){// (i, j) 这个位置放k是否合适
                        if(isValid(i,j,k,board)){
                            board[i][j]=k;   // 放置k
                            if(backtracking(board))
                                return true;// 如果找到合适一组立刻返回
                            board[i][j]='.';   // 回溯,撤销k
                        }
                    }
                    return false; // 9个数都试完了,都不行,那么就返回false
                    
                }
            
            }
        }
        return true;// 遍历完没有返回false,说明找到了合适棋盘位置了
    }
    void solveSudoku(vector<vector<char>>& board) {
        backtracking(board);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值