剑指offer第二版-13.机器人的运动范围(回溯法)

本系列导航:剑指offer(第二版)java实现导航帖

面试题13:机器人的运动范围

题目要求:
地上有一个m行n列的方格,一个机器人从坐标(0,0)的各自开始移动,它每次可以向上下左右移动一格,但不能进入横纵坐标数位之和大于k的格子。
例如,当k等于18时,机器人能进入(35,37),因为3+5+3+7=18;但却不能进入(35,38),因为3+5+3+8=19>18。
请问该机器人能够到达多少个格子。

解题思路:
本题依旧考察回溯法。
每前进一步后,可选移动项为上下左右四个;为了判断某一个格子是否可以进入从而进行计数,不仅需要考虑边界值,计算各位数字之和,更要判断该格子是否已经被访问过,。所以需要一个布尔矩阵,用来记录各格子是否已被访问。整体思路与12题类似,具体请参考本系列的导航帖

package chapter2;
/**
 * Created by ryder on 2017/7/4.
 * 机器人的运动范围
 */
public class P92_RobotMove {
    //依旧回溯
    public static int movingCount(int threshold,int rowLen,int colLen){
        if(rowLen<=0 || colLen<=0 || threshold<0)
            return 0;
        boolean[][] visitFlag = new boolean[rowLen][colLen];
        for(int row=0;row<rowLen;row++){
            for(int col=0;col<colLen;col++)
                visitFlag[row][col] = false;
        }
        return movingCountCore(threshold,rowLen,colLen,0,0,visitFlag);
    }
    public static int movingCountCore(int threshold,int rowLen,int colLen,int row,int col,boolean[][] visitFlag){
        int count = 0;
        if(canGetIn(threshold,rowLen,colLen,row,col,visitFlag)){
            visitFlag[row][col] = true;
            count = 1+movingCountCore(threshold,rowLen,colLen,row-1,col,visitFlag)+
                    movingCountCore(threshold,rowLen,colLen,row+1,col,visitFlag)+
                    movingCountCore(threshold,rowLen,colLen,row,col-1,visitFlag)+
                    movingCountCore(threshold,rowLen,colLen,row,col+1,visitFlag);
        }
        return count;
    }
    public static boolean canGetIn(int threshold,int rowLen,int colLen,int row,int col,boolean[][] visitFlag){
        return row>=0 && col>=0 && row<rowLen
                && col<colLen && !visitFlag[row][col]
                && getDigitSum(row)+getDigitSum(col)<=threshold;
    }
    public static int getDigitSum(int number){
        int sum=0;
        while (number>0){
            sum += number%10;
            number/=10;
        }
        return sum;
    }

    public static void main(String[] args){
        System.out.println(movingCount(0,3,4)); //1
        System.out.println(movingCount(1,3,4)); //3
        System.out.println(movingCount(9,2,20)); //36
    }
}

运行结果

1
3
36

推荐阅读更多精彩内容

  • 题目描述地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一...
    yangqi916阅读 749评论 0 1
  • 题目描述:地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动...
    鬼谷神奇阅读 1,020评论 0 0
  • 回溯-机器人的运动范围 题目描述 地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左...
    Jacinth阅读 182评论 0 0
  • 剑指 offer 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成...
    faremax阅读 1,147评论 0 7
  • 题目要求 地上有一个m行n列的方格,一个机器人从坐标(0,0)的位置开始移动,他每次可以向左,右,上,下移动一格,...
    小庄bb阅读 565评论 0 0