剑指Offer-机器人的运动范围

剑指Offer-机器人的运动范围

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

示例 1:

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

思路

与《矩阵中的路径》那道题类似,也是dfs+回溯,不过这道题有一些可以优化的点。

首先,通过分析解的情况,我们可以知道机器人只能向右或者向下走(类似一个直角三角形),排除向左和向上走的情况。

利用一个记忆矩阵visited,标识已经走过的路。不能重复地走。也是为了递归函数的出栈。

class Solution {

    //记忆矩阵
    boolean[][] visited;
    public int movingCount(int m, int n, int k) {
        //对记忆矩阵初始化
        this.visited=new boolean[m][n];
        return dfs(m,n,0,0,k);

    }

    public int dfs(int m,int n,int i,int j,int k)
    {
        if(i<0 || i>=m || j<0 || j>=n || getSum(i,j)>k || visited[i][j])
        {
            return 0;
        }
        //设置标记,回溯回来的时候直接返回
        visited[i][j]=true;
		//这里直接返回,与《矩阵中路径》那题不同,因为那题是穷举所有可能性,这题是找最大值,且不会
        //遍历矩阵中所有元素,只是从(0,0)点出发深搜回溯而已。
        
        //根据直角三角形的形状,只向右或向下走。
        return 1+(dfs(m,n,i+1,j,k) + dfs(m,n,i,j+1,k));
    }

    //获得某个点横纵座标的位数和的函数
    public int getSum(int x,int y)
    {
        int sum=0;
        while(x>0)
        {
            sum+=x%10;
            x=x/10;
        }
        while(y>0)
        {
            sum+=y%10;
            y=y/10;
        }
        return sum;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章