基础算法-回溯算法-案例

现象:

基础算法-回溯算法-案例

  • 基础算法-回溯算法
  • 从不同角度出发 去寻找答案 找到答案或者走不通了(根据需求:找一个答案还是列举全部答案) 则回溯返回
  • 继续从下一条路出发 去寻找答案, 一直到走完

常见案例:

案例一:
通过输入一个不重复数组如:[1,2,3]
使用数组中的元素不重复排列组成不同数组如 {1,2,3}{1,3,2},{2,1,3},{2,3,1},{3,1,2},{3,2,1}

在这里插入图片描述

  • 思路:
    • 第一步: 第一层: 先循环数组,将数组第一个元素放临时list,临时数组=[1]
    • 第二步: 递归调用在第二层, 在循环中,数组中下一个不重复元素放入临时数组,临时数组=[1,2]
    • 第四步: 递归调用在第三层, 在循环中,数组中下一个不重复元素放入临时数组,临时数组=[1,2,3] 此时第三次迭代的循环已经走完
    • 第五步: 递归调用在第四层, 此时判断临时数组的长度满足要求了,将临时数组结果放最终结果集,跳出这次递推,回到第三层递推函数
    • 第六步: 回到第三层, 此时循环已经走完,执行第三层的回溯删除,移除临时数组最后一个元素,临时数组=[1,2] 此时第三层迭代函数走完
    • 第七步: 回到第二层, 执行回溯删除,移除数组最后一个元素,临时数组=[1]
    • 第八步: 第二层, 循环继续,在循环中,数组中下一个元素放临时数组,临时数组=[1,3]
    • 第九步: 递归调用进入第三层, 在循环中,数组下一个不重复元素放入临时数组,临时数组=[1,3,2]
    • 第十步: 递归调用进入第四层, 此时判断临时数组的长度满足要求了,将临时数组结果放最终结果集,跳出这次递推,回到第三层递推函数
    • 第十一步: 回到第三层, 此时循环已经走完,执行第三层的回溯删除,移除临时数组最后一个元素,临时数组=[1,3] 此时第三层迭代函数走完
    • 第十二步: 回到第二层, 执行回溯删除,移除数组最后一个元素,临时数组=[1],此时第二层函数循环走完
    • 第十三步: 回到第一层, 执行回溯删除,移除数组最后一个元素,临时数组=[0] 此时完成了第一层的第一次迭循环,临时数组也清空了
    • 第十四步: 第一层: 继续执行第一层的循环,将数组第二个元素放list 临时数组=[2]
    • 继续执行第二…到…第十三步 一直到最外层循环走完,所有结果都将存放在结果集,临时数组也清空状态

代码方法:


    /** 最终结果存放容器 */
    static List<List<Integer>> result = new ArrayList<>();


    public static void main(String[] args){
        int[] a ={1,2,3};
        arrList(a, new ArrayList<>());

        for (List<Integer> list: result) {
            log.debug("list:{}",list);
        }
    }

    /**
     * 通过输入一个不重复数组
     * 使用数组中的元素不重复排列组成不同数组
     *
     * 思路:
     * 第一步: 第一层: 先循环数组,将数组第一个元素放临时list,临时数组=[1]
     * 第二步: 递归调用在第二层, 在循环中,数组中下一个不重复元素放入临时数组,临时数组=[1,2]
     * 第四步: 递归调用在第三层, 在循环中,数组中下一个不重复元素放入临时数组,临时数组=[1,2,3] 此时第三次迭代的循环已经走完
     * 第五步: 递归调用在第四层, 此时判断临时数组的长度满足要求了,将临时数组结果放最终结果集,跳出这次递推,回到第三层递推函数
     * 第六步: 回到第三层, 此时循环已经走完,执行第三层的回溯删除,移除临时数组最后一个元素,临时数组=[1,2] 此时第三层迭代函数走完
     * 第七步: 回到第二层, 执行回溯删除,移除数组最后一个元素,临时数组=[1]
     * 第八步: 第二层, 循环继续,在循环中,数组中下一个元素放临时数组,临时数组=[1,3]
     * 第九步: 递归调用进入第三层, 在循环中,数组下一个不重复元素放入临时数组,临时数组=[1,3,2]
     * 第十步: 递归调用进入第四层, 此时判断临时数组的长度满足要求了,将临时数组结果放最终结果集,跳出这次递推,回到第三层递推函数
     * 第十一步: 回到第三层, 此时循环已经走完,执行第三层的回溯删除,移除临时数组最后一个元素,临时数组=[1,3] 此时第三层迭代函数走完
     * 第十二步: 回到第二层, 执行回溯删除,移除数组最后一个元素,临时数组=[1],此时第二层函数循环走完
     * 第十三步: 回到第一层, 执行回溯删除,移除数组最后一个元素,临时数组=[0]  此时完成了第一层的第一次迭循环,临时数组也清空了
     *
     * 第十四步: 第一层: 继续执行第一层的循环,将数组第二个元素放list 临时数组=[2]
     * 继续执行第二...到...第十三步 一直到最外层循环走完,所有结果都将存放在结果集,临时数组也清空状态
     *
     */
    public static void arrList(int[] arr, List<Integer> list){

        // 定义一个临时list 接受入参list
        List<Integer> tempList=new ArrayList<>(list);

        if(tempList.size()==arr.length){
            // 临时list长度满足要求了 放最终结果集
            result.add(tempList);
            // 返回这次递归 回到上次递归的循环中 执行上一层回溯remove删除方法
            return;
        }

        for (int i=0;i<=arr.length-1;i++){
            // 控制元素不能重复
            if(tempList.contains(arr[i])){
                continue;
            }
            tempList.add(arr[i]);
            // 递归调用
            arrList(arr,tempList);
            // 回溯关键:每次循环走完 就开始逐步减少最后一个元素
            tempList.remove(tempList.size()-1);
        }

结果:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值