剑指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。请问该机器人能够到达多少个格子?

示例 1:

输入:m = 2, n = 3, k = 1

输出:3

示例 2:

输入:m = 3, n = 1, k = 0

输出:1

提示:

  • 1 <= n,m <= 100
  • 0 <= k <= 20

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof

思路

这题很容易误解, 直接遍历整个二维数组,判断是否小于k,小于就说明满足条件 ,这样子做就不对了。

因为有些格子他的行坐标和列坐标的数位之和小于k,但是,机器人也到不了这里。因为机器人只能上下左右移动,有些满足小于k的格子被挡住了。

看到 上、下、左、右 四个方向就要马上想到搜索,这题是一道比较典型的搜索题目。

  • c++代码
class Solution {
private:
    int movDistance[4][2] = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
    int flag[101][101] = {0};
    int ans = 0;

    void dfs(int x, int y, int m, int n, int k) {
        flag[x][y] = 1;
        for (int i = 0; i < 4; ++i) {
            int mx = x + movDistance[i][0], my = y + movDistance[i][1];
            if (0 <= mx && mx < m && 0 <= my && my < n && !flag[mx][my] && sum(mx, my) <= k) {
                ++ans;
                dfs(mx, my, m, n, k);
            }
        }
    }
    int sum(int x, int y) {
        return (x % 10 + x / 10) + (y % 10 + y / 10); // 因为题目说了0 <= n, m <= 100, 所以这里简化写法了。
    }
public:
    int movingCount(int m, int n, int k) {
        dfs(0, 0, m, n, k);
        return ans + 1;
    }
};
  • python代码
class Solution:
    def __init__(self):
        self.ans = 0
        self.mvDistance = [[-1, 0], [1, 0], [0, -1], [0, 1]]
        self.flag = [[0] * 101 for i in range(102)]

    def movingCount(self, m: int, n: int, k: int) -> int:
        def my_sum(x, y):
            return (x // 10 + x % 10) + (y // 10 + y % 10)

        def dfs(x, y, m, n, k):
            self.flag[x][y] = 1
            for i in range(4):
                mx, my = x + self.mvDistance[i][0], y + self.mvDistance[i][1]
                if 0 <= mx < m and 0 <= my < n and not self.flag[mx][my] and my_sum(mx, my) <= k:
                    self.ans += 1
                    dfs(mx, my, m, n, k)

        dfs(0, 0, m, n, k)
        return self.ans + 1

总结

搜索之类的题目,基本上都是有模板可以套的,千万不要去人肉递归,这样之会越搞越糊涂,要是不理解,画个递归树还是可以的。真正掌握这种题,还是要多刷,刷多了就有感觉了。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值