【剑指Offer】机器人的运动范围(dfs递归思想;bfs)

题目

地上有一个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

思路

dfs递归思想

虽然说每个点可以往四个方向走,但是考虑到是从[0,0]走到右下的某目标点,所以只需要考虑向右和向下的方向就可以了。对于递归过程中的一些参数,设置了全局变量。

  • 时间复杂度O(MN)
  • 空间复杂度O(MN)
class Solution {
public:
    int movingCount(int m, int n, int k) {
        //初始化
        nrows = m;
        ncols = n;
        limit = k;
        for(int i=0; i<m; i++){
            for(int j=0; j<n; j++){
                flag[i][j] = 0;
            }
        }

        return dfs(0,0);
    }
private:
    int nrows, ncols, limit;
    int flag[100][100];
    int dfs(int x, int y){
        //终止条件
        if( x >=nrows || y>= ncols || flag[x][y]==1 ||  (computeSum(x)+computeSum(y)>limit) ){
            return 0;
        }
        //每个结点可以选择向右或者向下走
        flag[x][y] = 1;
        return 1 + dfs(x+1,y) + dfs(x,y+1);
    }
    int computeSum(int a){
        int sum = 0;
        while( a>0 ){
            sum += a%10;
            a = a/10;
        }
        return sum;
    }
};

在这里插入图片描述

bfs

每次取出队列的所有结点,然后每个结点可以选择向右或右下试探,如果没问题就加入队列。如此循环直到队列为空。

  • 时间复杂度O(MN)
  • 空间复杂度O(MN)
class Solution {
public:
    int movingCount(int m, int n, int k) {
        queue<pair<int,int> > que;
        int flag[m][n];
        for(int i=0; i<m; i++){
            for(int j=0; j<n; j++){
                flag[i][j] = 0;
            }
        }
        //出发点
        que.push({0,0});
        flag[0][0] = 1;
        int anws = 1;
        while( !que.empty() ){
            //取出队列所有点,每个点都往右往下试探
            int size = que.size();
            for(int i=0; i<size; i++){
                pair<int,int> node = que.front();
                que.pop();
                int x = node.first;
                int y = node.second;
                //往两个方向试探
                for(int j=0; j<2; j++){
                    int newx = x + dirs[j][0];
                    int newy = y + dirs[j][1];
                    if( newx<m && newy<n && flag[newx][newy]!=1 && (computeSum(newx)+computeSum(newy))<=k ){
                        que.push({newx,newy});
                        flag[newx][newy] = 1;
                        anws++;
                    }
                }
            }
        }
        return anws;
    }
private:
    int dirs[2][2] = {{1,0},{0,1}};
    int computeSum(int a){
        int sum = 0;
        while( a>0 ){
            sum += a%10;
            a = a/10;
        }
        return sum;
    }
};

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值