让初学者认识算法-回溯思想

回溯
有溯本清源的意思,就是往回走寻找根源

直接找一道题来看

class Solution {
    public List<List<Integer>> permute(int[] nums) {
        dfs(nums, 0);
        return ans;
    }
    List<List<Integer>> ans = new ArrayList<>();
    void dfs(int[] nums, int cur) {
        if (cur == nums.length) {
            List<Integer> list = new ArrayList<>();
            for (int i : nums) {
                list.add(i);
            }
            ans.add(list);
            return;
        }
        for (int i = cur; i < nums.length; i++) {
            swap(nums, cur, i);
            dfs(nums, cur + 1);
            swap(nums, cur, i);
        }
    }
    void swap(int[] nums, int i, int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
}

通过置换数组的元素这样可以遍历每一种排列形式,并且递归回来后数组是不会变的

因为我们在递归回来后也做了一次置换,这样可以使数组回到置换前的样子,这就是回溯

回溯只是一种思想
并不是一类特定的算法

递归其实也有回溯的意思

回溯是回到原来的位置
为什么要回到原来的位置
这个问题想清楚了递归回溯都会理解

递归内部可能会调用类中的属性
如果修改类中的属性所有的递归都会受影响

八皇后
int[] rows = new int[9]
int[] cold = new int[9]
标识行和列是否被占用(已经有皇后)

递归之前你需要标识当前位置已经有皇后(后面皇后不能出现在这个列这个行)
rows[i] = 1
cols[j] = 1

这里有对角线我先不说

主要是要明白为什么回来的时候还需要
rows[i] = 0
cols[j] = 0
就是因为对下一次循环来说这个ij是未被选中的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值