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

解题思路

第一眼看到想用迭代,然后失败了(主要是理解题意有问题),再次尝试用递归,然后超时,最后还是选择迭代,在迭代时主要涉及到两个点:

  • 当前位置的坐标和必须满足条件,即所有位的和<k。
  • 当前位置必须有相邻的点为能够到达的点。

我选择的办法是用了一个标记数组,将[0,0]点标记为true,然后对数组进行一次遍历,如果当前点为true,则判断该点的右边和下边的相邻点是否满足条件,如果满足,则将其标记为true,最后统计数组中为true的点的数目即可。

代码

递归代码(超时无法通过):

class Solution {
    public int movingCount(int m, int n, int k) {
        int res=0;
        boolean[][] state=new boolean[m][n];
        res=get_numbers(state,0,0,k);
        return res;
    }

    public int get_numbers(boolean[][] state,int m,int n,int k){
        if((m%10+m/10+n%10+n/10)>k||m>=state.length||n>=state[0].length){
            return 0;
        }
        int res=0;
        if(!state[m][n]){
            state[m][n]=true;
            res++;
        }
        return get_numbers(state,m+1,n,k)+get_numbers(state,m,n+1,k)+res;
    }
}

我在思考一个问题:递归中如果加限制条件是否可以完成该题目?(暂时没解决)
迭代代码:

class Solution {
    public int movingCount(int m, int n, int k) {
        int res=0;
        boolean[][] state=new boolean[m][n];
        state[0][0]=true;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(state[i][j]){
                    if(i<m-1){
                        if(get_number(i+1,j)<=k){
                            state[i+1][j]=true;
                        }
                    }
                    if(j<n-1){
                        if(get_number(i,j+1)<=k){
                            state[i][j+1]=true;
                        }
                    }
                    
                }
            }
        }
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(state[i][j]){
                    res++;
                }
            }
        }
        return res;
    }
    public int get_number(int m,int n){
        int sum=0;
        if(m==100){
            sum=sum+1;
        }else{
            sum=sum+m/10+m%10;
        }
        if(n==100){
            sum=sum+1;
        }else{
            sum=sum+n/10+n%10;
        }
        return sum;
    }
}

这是官方解法中的一种,还有一种解法是广度优先,通过一次循环遍历计算到达每个点时在该点所能到达的格子数,而每个点的格子数为其上方和左方的格子数之和,这两种方法大同小异,时间复杂度和空间复杂度也没区别,细细想想即可完成,可以尝试一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值