算法练习- 搜索与回溯 LeetCode 剑指 Offer 13. 机器人的运动范围

今日心情:就是感觉自己啥也不会 😭😭

题目描述:

剑指 Offer 13. 机器人的运动范围

地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?

 

 


解题代码:(来自leetcode题解)

class Solution {

    int m,n,k;
    boolean[][] visited;

    public int movingCount(int m, int n, int k) {
        this.m = m;
        this.n = n;
        this.k = k;
        this.visited = new boolean[m][n];
        int count = dfs(0,0,0,0);
        return count;
    }

    public int dfs(int i, int j, int s_i, int s_j){
        
        //不可达点判断(返回0)
        //1. 越界
        //2. 超过k
        //3. 已经被访问过
        if(i >= m || j >= n || s_i + s_j > k || visited[i][j]){
            return 0;
        }        
        // 当前节点以及被访问,更新visited表
        visited[i][j] = true;
        // 递归
        //求坐标的位数和(注意是下一个的)例如:[19,20] [21,22]
        int ns_i = (i+1)%10 != 0 ? s_i+1:s_i-8;
        int ns_j = (j+1)%10 != 0 ? s_j+1:s_j-8;

        int res = 1 + dfs(i+1,j,ns_i,s_j) + dfs(i,j+1,s_i,ns_j);
        return res;
    }

}

解题思路:(参考的 leetcode 题解+自己的理解和思考)

(1)由于k的限制条件,所以需要判断m,n构成的位置是否具有可达性且满足条件。

(2)需要计算位置的数位和,然后再判断是否小于 k 值。

(3)通过递归回溯搜索所有满足条件的可达点。

(4)所有到达访问过的点需要进行记录标记,避免重复访问,造成重复计数。


代码解析:

(1)定义全局变量

        int m,n,k;  boolean[][] visited;

(2)通过movingCount(int m, int n, int k) 函数传进来的参数,赋值给全局变量,个人认为是因为可以减少dfs 递归函数的参数数量,直接使用全局变量进行操作。

(3)实现 dfs(int i, int j, int s_i, int s_j) 函数 递归回溯函数

              不可达点判断(返回0):1. 越界 2. 超过k 3. 已经被访问过 

              if(i >= m || j >= n || s_i + s_j > k || visited[i][j]){return 0;}

              否则,标记当前点已经访问搜索过,更新visited表:visited[i][j] = true;

              如果没有返回0则说明当前点满足条件,此时搜寻找下一个点(向下或者向右搜寻)。

              求坐标的位数和(注意是下一个的)例如:自己可以找例子实施这个求和公式

               比如说:点 [19,20] , [21,22]

                int ns_i = (i+1)%10 != 0 ? s_i+1:s_i-8;

                int ns_j = (j+1)%10 != 0 ? s_j+1:s_j-8;

                然后加1(此时访问点满足条件进行计数) 递归 向下 或者 向右进行搜索 

                int res = 1 + dfs(i+1,j,ns_i,s_j) + dfs(i,j+1,s_i,ns_j);

                然后返回 res 计数值。

    (4)在movingCount(int m, int n, int k) 函数中调用,因为  int m,n,k;  boolean[][] visited; 为全局变量所以直接从 [0, 0] 开始,此时位数和分别为 0, 0

              调用 dfs(0,0,0,0) 进行回溯搜索,返回所有可达切满足k条件的点。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值