剑指刷题日记剑指 剑指 Offer 13. 机器人的运动范围

题目描述

题目链接:https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/solution/mian-shi-ti-13-ji-qi-ren-de-yun-dong-fan-wei-dfs-b/
在这里插入图片描述

解题思路

这一题与上一题有点相似,都是用递归DFS的思想
剑指 Offer 12. 矩阵中的路径
不同点在于,上一题是求一条与字符串配对的通路,这一题是求可达区域。
求通路的话,可以是由中间某个点开始配对,往上下左右四个方向深搜继续寻找配对的,所以深搜的话四个方向都得走。
在这里插入图片描述
那求可达区域呢?
如果从(0,0)作为入口深搜,根据可达解的结构和连通性,仅通过向右和向下移动,访问所有可达解 。退一步讲,就是遍历一个矩阵中的所有元素,如果从某一个顶点出发(左上角,右上角,左下角,右下角),仅通过向两个方向进行深搜便可完成。
在这里插入图片描述
图片来源:
在这里插入图片描述

作者:jyd
链接:https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/solution/mian-shi-ti-13-ji-qi-ren-de-yun-dong-fan-wei-dfs-b/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

而此题要求求可达区域的总点数,类似于求二叉树的结点总数dfs(left)+dfs(right)+1 左子树结点数+右子树结点数+本身)
或者求二叉树的深度,比较两者中的最大值再加本身剑指 Offer 55 - I. 二叉树的深度(left>right?left:right)+1, 笔记剑指刷题日记剑指 剑指 Offer 55 - I. 二叉树的深度

只不过二叉树访问结点时不需要标记,因为一个结点只能有一个父亲结点。但是因为在这里是矩阵,某一个结点的右边"儿子"可能是某一个结点的下边"儿子",所以需要标记,否则可能就会重复计数。由于某一个结点最多访问一次,要么可以进入,要么不可以进入,因此不需要跟上一题一样撤销标记,上一题需要撤销标记的原因是因为某一结点可以被访问多次,可以详见上一题的笔记剑指刷题日记剑指 剑指 Offer 12. 矩阵中的路径)。
解答代码如下:

class Solution {
public:

    int movingCount(int m, int n, int k) {
        vector<vector<int>> visit(m, vector<int>(n,0));
        return dfs(visit, m,n,0, 0, k);
    }

    int dfs(vector<vector<int>> &visit, int m, int n, int x, int y, int k)  // 改变vector的值,传入引用
    {

        if(x>=m || y>=n || visit[x][y] || (x/10+x%10+y/10+y%10)>k)   // 注意边界值是等于行数或者列数,不要减1
            return 0; 
        
        // 能执行以下语句说明,能够进入坐标为(x,y)的格子
        // 标记
        visit[x][y] = 1;

        int down = dfs(visit, m,n,x+1, y, k);
        int right = dfs(visit, m,n,x, y+1, k);

        // 不需要解除标记,所有的格子最多访问一次,不像上一题可能要访问多次
        return down+right+1;
    }

};

猜想: 矩阵的顶点是否可以当作根节点?(中间的元素可以上下左右四个方向,但是顶点就两个)然后它只能往两个方向走,另外两个方向不就可以当作它的"左右子树"了?
在这里插入图片描述
仔细看看这几局,是不是像极了二叉树的先序遍历(访问当前结点->遍历左子树->遍历右子树)?

只不过二叉树访问结点时不需要标记,因为一个结点只能有一个父亲结点。但是因为在这里是矩阵,某一个结点的右边"儿子"可能是某一个结点的下边"儿子",所以访问当前结点的操作就变成了标记当前结点,表示已访问过。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值