递归之回溯

递归之回溯

在许多的实际问题中,使用常规的算法十分难以解决一些具有递推性质的问题。但递推性质刚好和我们的递归相符合,而回溯也可以算是递归中的一种


我们最常见的回溯的算法就是八皇后的算法了
回溯法解决八皇后问题


我们在学习数据结构时的深度优先算法就是一种回溯
或者我们学习二叉树时三种遍历的方式在我看来也有回溯
回溯一般用在什么情景之下呢?
类似于寻找迷宫出口,遍历集合的子集之类的问题


回溯最重要的是在不成立的情况下使我们结果的状态返回为上一个递归的状态

下面来两个回溯的例子
一个是查找一个字符矩阵中连续的字符串是否存在的问题

public static boolean[][] flag;


    public static boolean exist(char[][] board, String word){
        //初始化标记矩阵,false为没走过
        flag = new boolean[board.length][board[0].length];
        for(int i=0;i<board.length;i++){
            for(int j=0;j<board[0].length;j++){
                if(board[i][j]==word.charAt(0)&&find(board, word, i, j, 0))
                    return true;
            }
        }
        return false;
    }


    public static boolean find(char[][] board,String word,int i,int j,int num){//分别代表目标矩阵
        //目标字符串,矩阵中元素的坐标,字符串的字符坐标
        if(num==word.length())
                   return true;
        //如果坐标已经超出界限,返回false
        if(i<0||i>board.length-1||j<0||j>board[0].length-1||board[i][j]!=word.charAt(num)||flag[i][j])
            return false;

        //标记矩阵坐标i,j已经被走过
        flag[i][j]=true;
        //如果返回的时false,那么就回溯
        if(find(board,word,i+1,j,num+1)||find(board,word,i-1,j,num+1)||
                find(board,word,i,j+1,num+1)||find(board,word,i,j-1,num+1))
            return true;
        //回溯
        flag[i][j]=false;
        return false;
    }

仔细揣摩一些收获颇丰



还有一道是查找出所有符合的子集

public static List<List<Integer>> res = new ArrayList<>();

    public static List<List<Integer>> conbinationSum(int[] candidates,int target){
        Arrays.sort(candidates);
        List<Integer> list = new ArrayList<>();

        find(candidates, list, 0, target, 0);

        return res;
    }

    public static void find(int[] candidates,List<Integer>list,int sum, int target,int index){
        //目标数组事先是排过队的
        //参数分别是目标数组,需要添加的集合,当前的总和,目标数,当前的下标
        if(sum>target){
            return;
        }
        if(sum==target){//一个完整的解
            res.add(list);
            return;
        }
        for (int i = index; i < candidates.length; i++) {
            List<Integer> t_list = new ArrayList<>(list);
            t_list.add(candidates[i]);
            find(candidates, t_list, sum + candidates[i], target,i);
        }

    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值