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

示例 1:

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

示例 2:

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

提示:

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

解题思路

这道题求运动范围,依然是矩阵,只是改变了限制条件。这种一般都是使用回溯法来解决(与八皇后问题是一类问题)。

1.确定是否需要返回值:

由于需要计算具体的值,并且有限制条件,不是递归完所有情况,所以需要有返回值。这里求的是个数,因此返回值类型为int。

2.确定边界条件:

这道题结束循环的条件很简单,首先是下标不能越界,否则返回0.

其次是计算坐标的数位之和。如果>k,则返回0.

另外,为了解决重复计数的问题,还需要设置一个数组用于记录当前位置的状态。因此条件中需要加:当前位置如果状态为已进入过,则返回0.

3.单层递归逻辑

首先,进入的第一个位置是确定的,为[0,0]。

另外,从第一个位置开始,要遍历的方向有四个(上下左右)。

由于递归函数返回值是个数(int),因此只需记录下每个方向的返回值,最后四个方向的返回值之和再加上出发位置的1个格子,得到的值即为机器人所能到达的所有格子数。

4.这道题只是判断能否到达,因此不需要记录路径,只需要求和。

其他解法:

看到题解中有大佬使用了并查集(用于计算连通域的面积),但是并查集我还不会,留个坑。

Java解法

class Solution {
    public int movingCount(int m, int n, int k) {
        int res = 0;
        int [][] flag = new int [m][n];
        res = helper(m,n,k,0,0,flag);
        return res;

    }
    public int helper(int m,int n,int k,int l,int r,int [][] flag){
        if(l==m || r==n || l<0 || r<0 || flag[l][r]==1) return 0;
        if(getSum(l,r)>k) return 0;
        flag[l][r]=1;
        int up = helper(m,n,k,l-1,r,flag);
        int down = helper(m,n,k,l+1,r,flag);
        int left = helper(m,n,k,l,r-1,flag);
        int right = helper(m,n,k,l,r+1,flag);
        
        return up+down+left+right+1;
    }
    public int getSum(int l,int r){
        int res = 0;
        res+=(l/100);
        res+=(l%100/10);
        res+=(l%10);
        res+=(r/100);
        res+=(r%100/10);
        res+=(r%10);
        return res;
    }
}

猜你喜欢

转载自blog.csdn.net/paranior/article/details/115398522