leetcode day14 (中等)搜索与回溯算法

文章讲述了如何使用深度优先搜索(DFS)结合回溯算法解决两个编程问题:在二维矩阵中寻找特定单词的路径以及计算机器人在给定限制下的运动范围。对于矩阵中的路径问题,关键在于设置递归结束条件和正确回溯。而在机器人的运动范围问题上,初始的双重循环解决方案并不完备,需要利用DFS来处理道路上可能存在的障碍。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天的题刚做还挺有难度的,但是大差不差,能记住这种套路解决搜索与回溯问题就行。

剑指 Offer 12. 矩阵中的路径

思路:dfs+回溯算法。

        需要的参数有:二维数组board;当前位置i、j;访问标记数组visited;单词遍历指针start

        递归结束条件:i/j指针越界;当前元素已被访问过(visited);当前元素与单词元素不一致。

        若start遍历至最后一个单词元素,表示能在board中找到访问路径。

        注意 : 遍历至board[i][j]时,对应visited[i][j]应设置为true;当前路径不通时,需要回溯,记得visited[i][j]重新设为false.

public boolean exist(char[][] board, String word) {
        if (board == null || board.length == 0 || board[0].length == 0)
            return false;
        char[] chars = word.toCharArray();
        boolean[][] visited = 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 (dfs(board,chars,visited,i,j,0)){
                    return true;
                }
            }
        }
        return false;
    }
    private boolean dfs(char[][] board,char[] chars,boolean[][] visited,int i,int j,int start){
        if (i<0 || i>=board.length || j<0 || j>=board[0].length || chars[start]!=board[i][j] || visited[i][j]){
            return false;
        }
        if (start == chars.length-1)
            return true;
        visited[i][j] = true;
        boolean ans = false;
        ans = dfs(board,chars,visited,i-1,j,start+1) ||
                dfs(board,chars,visited,i+1,j,start+1) ||
                dfs(board,chars,visited,i,j-1,start+1) ||
                dfs(board,chars,visited,i,j+1,start+1);
        visited[i][j] = false;
        return ans;
    }

面试题13. 机器人的运动范围

思路:(错误的)刚开始想的是双重循环,分别算出横纵坐标的十位、个位数字,相加<=k则count+1。这种解法未考虑路上有故障的情况,比如 m=n=12,k=1。理论上[10,0]或者[0,10]是可以访问的,但[9,0]/[0,9]不能访问,因此不能通过[9,0]到达[10,0]。

        考虑到上述情况,仍使用dfs+回溯。跟上题很像,递归结束条件是:i/j越界;当前元素已被访问过;各位元素之和>k。若当前元素满足条件,则搜索附近格子,注意此时count+1。

public int movingCount(int m, int n, int k) {
        boolean[][] visited = new boolean[m][n];
        return dfs(0,0,m,n,k,visited);
    }
    private int dfs(int i,int j,int m,int n,int k,boolean visited[][]){
        if (i<0 || i>=m || j<0 || j>=n || (i/10+i%10+j/10+j%10)>k || visited[i][j]){
            return 0;
        }
        visited[i][j] = true;
        return dfs(i-1,j,m,n,k,visited)+dfs(i+1,j,m,n,k,visited)+
                dfs(i,j-1,m,n,k,visited)+dfs(i,j+1,m,n,k,visited)+1;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值