算法模板 -- 回溯算法模板

回溯

带你深度解析回溯算法之 《回溯算法从入门到精通

回溯算法模板

// 伪代码
List<Value> result;
void backtrack(路径, 选择列表) {
    if (满足结束条件){
        result.add(路径);
        return;
    }
    for (选择 : 选择列表) {
        做选择;
        backtrack(路径, 选择路径);
       	撤销选择;
    }
}

例1 : 全排列 (LeetCode. 46)

题目描述:给定一个 没有重复 数字的序列,返回其所有可能的全排列。

class Solution {
    List<List<Integer>> res = new LinkedList<>();

    public List<List<Integer>> permute(int[] nums) {
        LinkedList<Integer> track = new LinkedList<>();
        backtrack(nums, track);
        return res;
    }

    void backtrack(int[] nums, LinkedList<Integer> track) {
        // 定义出口
        if (track.size() == nums.length) {
            res.add(new LinkedList(track));
            return;
        }
        
        for (int i = 0; i < nums.length; i++) {
            // 剪枝 (排除不合法的选择)
            if (track.contains(nums[i])) continue;
            // 做选择
            track.add(nums[i]);
            // 进入下一层决策树
            backtrack(nums, track);
            // 撤销选择
            track.removeLast();
        }
    }
}

例2 : N皇后 (LeetCode. 51)

题目描述:设计一种算法,打印 N 皇后在 N × N 棋盘上的各种摆法,其中每个皇后都不同行、不同列,也不在对角线上。每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。

class Solution {
    List<List<String>> result = new ArrayList<>();
    public List<List<String>> solveNQueens(int n) {
        backtrack(new ArrayList<>(), 0, n);
        return result;
    }

    public void backtrack(List<String> list, int row, int n) {
        // 满足条件,加入到结果列表中,然后返回。
        if(row == n) {
            result.add(new ArrayList<>(list));
            return;
        }
        for(int i = 0; i < n; i++) {
            // 如果放置在该位置合法,则进行递归
            if(isValid(i, list, row, n))
                continue;
            // 生成该行的字符串
            list.add(generateString(i, n));
            backtrack(list, row+1, n);
            list.remove(list.size() - 1);
        }
    }

    public boolean isValid(int pos, List<String> list, int row, int n) {
        // 判断竖着有没有重合的
        for(int i = 0; i < row; i++) {
            if(list.get(i).charAt(pos) == 'Q') {
                return false;
            }
        }
        // 判断斜向有没有重合的
        for(int i = row-1, j = pos-1; i >= 0 && j >= 0; i--, j--) {
            if(list.get(i).charAt(j) == 'Q') {
                return false;
            }
        }
        for(int i = row-1, j = pos+1; i >= 0 && j < n; i--, j++) {
            if(list.get(i).charAt(j) == 'Q') {
                return false;
            }
        }
        return true;
    }

    public String generateString(int pos, int n) {
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < pos; i++) {
            sb.append(".");
        }
        sb.append("Q");
        for(int i = pos+1; i < n; i++) {
            sb.append(".");
        }
        return sb.toString();
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值