回溯算法-暴力穷举思路

回溯算法框架如下


初始化结果集
主函数:接收传入参数、初始化(路径,选择列表)、执行回溯函数backtrack、返回结果集
回溯函数backtrack:判断结束条件(达到了就加入结果集并返回)、依次判断选择列表中的结果是否符合题中条件(不符合的跳过)、将第一个符合的结果加入路径并更改对应的标识、使用新的结果递归回溯函数、将结果从路径中拿掉并去掉对应的标识


for 选择 in 选择列表:
# 做选择
将该选择从选择列表移除
路径.add(选择)
backtrack(路径, 选择列表)
# 撤销选择
路径.remove(选择)
将该选择再加⼊选择列表

Leetcode 41 全排列(力扣

class Solution {
    LinkedList<List<Integer>> res = new LinkedList<>();
    public List<List<Integer>> permute(int[] nums) {
        /**
        回溯算法暴力破解
        新建一个结果数组
        主函数:声明track、used数组、以及递归函数
        一个track代表一个路径
         */
        
        LinkedList<Integer> track = new LinkedList<>();
        boolean[] used = new boolean[nums.length];
        backtrack(nums,track,used);
        return res;

    }
    void backtrack(int[] nums,LinkedList<Integer> track, boolean[] used){
        //结束条件
        if(track.size() == nums.length){
            res.add(new LinkedList(track));
            return;
        }
        for(int i = 0; i<nums.length; i++){
            if(used[i] == true){
                //该节点已加入track 剪枝
                continue;
            }
            //递归前做的事:加入节点,更改used
            track.add(nums[i]);
            used[i] = true;
            //递归
            backtrack(nums,track,used);
            //递归后做的事:删除节点,更改used
            track.removeLast();
            used[i] = false;
        }
        
    }
}

Leetcode 51 N皇后(力扣

class Solution {
    List<List<String>> result = new LinkedList<>();//存放所有结果
    public List<List<String>> solveNQueens(int n) {
        //新建一个棋盘
        List<String> board = new LinkedList<>();
        StringBuilder stringBuilder = new StringBuilder();
        //初始化棋盘 全部置空
        stringBuilder.append(".".repeat(n));
        for (int i = 0; i < n; i++) {
            board.add(stringBuilder.toString());
        }
        backTrack(0,board);
        return result;
    }
    //路径:board中小于row的那些行都已经成功放置了皇后
    //选择列表:第row行的所有列都是放置皇后的选择
    //结束条件:row 超过 board 的最后一行
    void backTrack(int row,List<String> board){
        //回溯终止条件
        if (row == board.size()){//终止条件 递归到了最后一个行 直接跳出
            result.add(new LinkedList<>(board));//将目前的结果中的添加到result中
            return;
        }
        int n = board.get(row).length();//获取当前游标所在的行的 String长度
        //开始穷举 从 当前行的 第0 列开始 处理节点
        for (int col = 0; col < n ; col++) {
            //处理节点 (检查节点合法性 , 如果合法 )
            if (!isValid(row,col,board)){//检查 当前行 的 所有列的节点是否合法
                continue;//如果不合法直接跳过
            }
            String str = board.get(row).substring(0,col) + 'Q' + board.get(row).substring(col+1);

            board.set(row,str);//将上述的替换后的String 代替到 游标所在的row

            //递归 深入子树
            backTrack(row+1,board);//对深入的下一行进行递归操作

            //回溯 ,撤销处理结果
            str = board.get(row).substring(0,col) + '.' + board.get(row).substring(col+1);
            board.set(row,str);
        }
    }
    boolean isValid(int row,int column,List<String> board){
        int n = board.size();
        //判断列位置是否合法
        for (int i = 0; i < n; i++) {
            if (board.get(i).charAt(column) == 'Q'){//第 i行 第 column 列 的字符
                return false;
            }
        }
        //判断是否与右上方发生冲突
        for (int i = row -1,j = column + 1; i >= 0 && j < n; i--,j++ ) {
            if (board.get(i).charAt(j) == 'Q'){
                return false;
            }
        }
        //判断 是否与 左上方冲突
        for (int i = row -1,j = column -1 ; i >=0 && j>=0 ; i--,j--) {
            if (board.get(i).charAt(j) == 'Q'){
                return false;
            }
        }
        return true;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值