首页 > 其他 > 详细

leetcode 17+79 回溯法

时间:2020-05-21 13:46:36      阅读:57      评论:0      收藏:0      [点我收藏+]

回溯是 DFS 的一种,它不是用在遍历图的节点上,而是用于求解  排列组合 问题,例如有 { ‘a‘,‘b‘,‘c‘ } 三个字符,求解所有由这三个字符排列得到的字符串。

在程序实现时,回溯需要注意对元素进行标记的问题。使用递归实现的回溯,在访问一个新元素进入新的递归调用,此时需要将新元素标记为已经访问,这样才能在继续

递归调用时不用重复访问该元素;但是在递归返回时,需要将该元素标记为未访问,因为只需要保证在一个递归链中不同时访问一个元素,而在不同的递归链是可以访问

已经访问过但是不在当前递归链中的元素。

回溯算法的标准格式:

    回溯法伪代码
    back(c,digits,offset,res){
        if(offset==length){
            res.add();
            return;
        }
        for(char c:String.toCharArray()){
            back(c,digits,offset+1,res);
        }
    }

leetcode 17

最终代码

class Solution {
    public static final String[] key={"","","abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
    // 回溯法伪代码
    // back(c,digits,offset,res){
    //     if(offset==length){
    //         res.add();
    //         return;
    //     }
    //     for(char c:String.toCharArray()){
    //         back(c,digits,offset+1,res);
    //     }
    // }
    public List<String> letterCombinations(String digits) {
        List<String> res=new ArrayList<>();
        if(digits!=null&&digits.length()!=0){
            back("",digits,0,res);
        }
        return res;//如果最终结果不对,可以直接诊断return附近哪里逻辑写错了
    }
    public void back(String pre,String digits,int offset,List<String> res){
        if(offset==digits.length()){
            res.add(pre);
            return;
        }
        String letters=key[digits.charAt(offset)-‘0‘];
        for(char ch:letters.toCharArray()){
            back(pre+ch,digits,offset+1,res);
        }
    }
    
}

 leetcode 79 

 

技术分享图片

这道题也毫无疑问地用回溯的迷宫找路完整版模版
    back(c,digits,offset,res){
        if(offset==length){
            res.add();
            return;
        }
        for(char c:String.toCharArray()){
            back(c,digits,offset+1,res);
        }
    }
    ******************************************
    exit(){
        for (int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(back()) return res;
            }
        }
    }
    back(char[][] board, String word, int start, int x, int y){
        if(start==word.length){
            return true;
        }
        //越界等找不到满足条件的路径的时候
        if(x<0||x>m||y<0||y<n||vis[][]==true||board[x][y]!=word.charAt(start)){
            return false;
        }
        board[x][y]=true;
        for(int i=0;i<4;i++){
            int nextx=x+dir[i][0];
            int nexty=y+dir[i][1];
            if(back(board,word,start+1,nextx,nexty)) return true;
        }
        //最重要的是如果四个方向都没有找到合适的路径,说明当前路径不合适,则应该对访问值进行回归
        vis[x][y]=false;
        return false;
    }

本题的完整版代码:

class Solution {
    // 这道题也毫无疑问地用回溯的迷宫找路完整版模版
    // back(c,digits,offset,res){
    //     if(offset==length){
    //         res.add();
    //         return;
    //     }
    //     for(char c:String.toCharArray()){
    //         back(c,digits,offset+1,res);
    //     }
    // }
    // ******************************************
    // exit(){
    //     for (int i=0;i<m;i++){
    //         for(int j=0;j<n;j++){
    //             if(back()) return res;
    //         }
    //     }
    // }
    // back(char[][] board, String word, int start, int x, int y){
    //     if(start==word.length){
    //         return true;
    //     }
    //     //越界等找不到满足条件的路径的时候
    //     if(x<0||x>m||y<0||y<n||vis[][]==true||board[x][y]!=word.charAt(start)){
    //         return false;
    //     }
    //     board[x][y]=true;
    //     for(int i=0;i<4;i++){
    //         int nextx=x+dir[i][0];
    //         int nexty=y+dir[i][1];
    //         if(back(board,word,start+1,nextx,nexty)) return true;
    //     }
    //     //最重要的是如果四个方向都没有找到合适的路径,说明当前路径不合适,则应该对访问值进行回归
    //     vis[x][y]=false;
    //     return false;
    // }
    public int[][] dir={{1,0},{-1,0},{0,1},{0,-1}};
    public boolean exist(char[][] board, String word) {
        int m=board.length;
        int n=board[0].length;
        boolean[][] vis=new boolean[m][n];
        for (int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(back(board,word,0,i,j,vis)) return true;
            }
        }
        return false;
    }
    public boolean back(char[][] board, String word, int start, int x, int y,boolean[][] vis){
        int m=board.length;
        int n=board[0].length;
        if(start==word.length()){
            return true;
        }
        //越界等找不到满足条件的路径的时候
        if(x<0||x>=m||y<0||y>=n||vis[x][y]==true||board[x][y]!=word.charAt(start)){
            return false;
        }
        vis[x][y]=true;
        for(int i=0;i<4;i++){
            int nextx=x+dir[i][0];
            int nexty=y+dir[i][1];
            if(back(board,word,start+1,nextx,nexty,vis)) return true;
        }
        //最重要的是如果四个方向都没有找到合适的路径,说明当前路径不合适,则应该对访问值进行回归
        vis[x][y]=false;
        return false;
    }
}

 

leetcode 17+79 回溯法

原文:https://www.cnblogs.com/sjh-dora/p/12929810.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!