当前位置:   article > 正文

递归之回溯_递归方法结束后会回到上一个

递归方法结束后会回到上一个

递归之回溯

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


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


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


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

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

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;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

仔细揣摩一些收获颇丰



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

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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/590435
推荐阅读
相关标签
  

闽ICP备14008679号