C++搜索算法之回溯法 backtracking

回溯法

回溯法是优先搜索的一种特殊情况,又称为试探法,常用于记录节点状态的深度优先搜索。
其核心是回溯,在搜索到某一节点的时候,如果发现目前节点及子节点并不是需求目标时,回退到原来的节点继续搜索,并且把目前节点修改的状态还原。
一般有两种情况,一种是修改最后一位输出,比如排列组合;一种是修改访问标记,比如矩阵里搜字符串。
**
题目一
给定一个无重复数字的整数数组,求其所有的排列方式
在这里插入图片描述

//对于每一个当前位置i,我们可以将其与之后的任意位置交换,然后继续处理位置i+1,直到处理最后一位

//主函数
vector<vector<int>>permute(vector<int>&nums){
    vector<vector<int>>ans;
    backtracking(nums,0,ans);
    return ans;
}

//辅函数
void backtracking(vector<int>&nums,int level,vector<vector<int>>&ans){
    if(level==nums.size()-1){
        ans.push_back(nums);
        return;
    }
    for(int i=level;i<num.size();i++){
        swap(nums[i],nums[level]);//修改当前节点状态
        backtracking(nums,level+1,ans);//递归子节点
        swap(nums[i],nums[level]);//回改当前节点状态
    }

题目二
给定一个整数n和一个整数k,求在1到n中选取k个数字的所有组合方法
在这里插入图片描述

//zhu 
vector<vector<int>>combine(int n,int k){
    vector<vector<int>>ans;
    vector<int>comb(k,0);
    int count=0;
    backtracking(ans,comb,count,1,n,k);
    return ans;
}
//fu
void backtracking(vector<vector<int>>&ans,vector,int&count,int pos,int n,int k){
    if(count==k){
        ans.push_back(comb);
        return;
    }
    for(int i=pos;i<=n,++i){
       comb[count++]=i;//修改当前节点状态
       backtracking(ans,comb,count,i+1,n,k);//递归子节点
       --count;//回改当前节点状态
   }
}

题目三

给定一个字母矩阵,所有的字母都与上下左右四个方向上的字母相连。给定一个字符串,求
字符串能不能在字母矩阵中寻找到。
![在这里插入图片描述](https://img-blog.csdnimg.cn/a697e89c65b74f7f83b7412921cb6173.png

//主函数
bool exist(vector<vector<char>>&board,string word){
    if(board.empty()) return false;
    int m=board.size(),n=board[0].size();
    vector<vector<bool>>visited(m,vector<bool>(n,false));
    bool find=false;
    for(int i=0;i<m;++i){
        for(int j=0;j<n;++j){
            backtracking(i,j,board,word,find,visited,0);
        }
    }
    return find;
}
//fuhanshu
void backtracking(int i,int j,vector<vector<char>>&board,string&word,bool&find,
    vector<vector<bool>>&visited,int pos){
    if(i<0||i>=board.size()||j<0||j>=board[0].size()){
        return;
    }
    if(visited[i][j]||find||board[i][j]!=word[pos]){
        return;
    }
    if(pos==word.size()-1){
        find==true;
        return;
    }
    visited[i][j]=true;//修改当前节点状态
    //递归子节点
    backtracking(i+1,j,board,word,find,visited,pos+1);
    backtracking(i-1,j,board,word,find,visited,pos+1);
    backtracking(i,j+1,board,word,find,visited,pos+1);
    backtracking(i,j-1,board,word,find,visited,pos+1);
    visited[[i][j]=false;//回改当前节点状态
}

题目四
给定一个大小为 n 的正方形国际象棋棋盘,求有多少种方式可以放置 n 个皇后并使得她们互
不攻击,即每一行、列、左斜、右斜最多只有一个皇后。例图如下:
在这里插入图片描述
在这里插入图片描述

//主函数
vector<vector<string>>solveNQueens(int n){
    vector<vector<string>>ans;
    if(n==0){
        return ans;
    }
    vector<string>board(n,string(n,','));
    vector<bool>column(n,false),ldiag(2*n-1,false),rdiag(2*n-1,false);
    backtranking(ans,board,column,ldiag,rdiag,0,n);
    return ans;
}
//fuhanshu
void backreacking(vector<vector<string>>&ans,vector<string>&board,vector<bool>&column,
    vector<bool>&ldiag,vector<bool>&rdiag,int row,int n){
    if(row==n){
        ans.push_back(board);
        return;
    }
    for(int i=0;i<n;++i){
        if(column[i]||ldiag[n-row+i-1]||rdiag[row+i+1]){
            continue;
        }
        //修改当前节点状态
        board[row][i]='Q';
        column[i]=ldiag[n-row+i-1]=rdiag[row+i+1]=true;
        //递归子节点
        backtracking(ans,board,column,ldiag,rdiag,row+1,n);
        //回改当前节点装填
        board[row][i]='.';
        column[i]=ldiag[n-row+i-1]=rdiag[row+i+1]=false;
    }
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,下面是使用 Python 编写随机算法回溯结合求解 n 皇后问题的代码。 ```python import random # 随机算法 def random_queen(n): queens = list(range(n)) while True: random.shuffle(queens) if not is_conflict(queens): return queens # 回溯算法 def backtracking_queen(n, row=0, queens=[]): if not queens: queens = [-1] * n if row == n: return queens for col in range(n): queens[row] = col if not is_conflict(queens, row): res = backtracking_queen(n, row + 1, queens) if res: return res queens[row] = -1 return None # 判断是否冲突 def is_conflict(queens, row=None): if row is None: row = len(queens) - 1 for i in range(row): if queens[i] == queens[row] or \ queens[i] - queens[row] == row - i or \ queens[i] - queens[row] == i - row: return True return False # 测试随机算法 queens = random_queen(8) print(queens) print(is_conflict(queens)) # 测试回溯算法 queens = backtracking_queen(8) print(queens) print(is_conflict(queens)) ``` 在上面的代码中,我们先定义了一个随机算法 `random_queen` 和一个回溯算法 `backtracking_queen`,然后分别使用这两个算法来求解 n 皇后问题。 其中,随机算法 `random_queen` 的思想是不断打乱皇后的位置,直到找到一组不冲突的方案为止。而回溯算法 `backtracking_queen` 则是通过递归的方式依次放置皇后,并检查是否冲突,如果冲突就回溯到上一行重新放置皇后。 在判断是否冲突的函数 `is_conflict` 中,我们通过检查同一列、同一对角线上是否已经存在皇后来判断是否冲突。 最后,我们分别使用随机算法回溯算法求解了 n 皇后问题,并在控制台输出了结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明月醉窗台

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值