机器人的运动范围
地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
//方法一:采用递归求解
public int movingCount(int threshold, int rows, int cols){
boolean [][] visit = new boolean[rows][cols]; //自动初始化为false
return countingSteps(threshold,rows,cols,0,0,visit);
}
private int countingSteps(int limit, int rows, int cols, int r, int c,boolean[][] visit) {
if( r < 0 || c < 0 || r >= rows || c >= cols || visit[r][c] == true
|| bitSum(r)+bitSum(c) > limit )
return 0;
visit[r][c] = true;
return countingSteps(limit,rows,cols,r+1,c,visit)+
countingSteps(limit,rows,cols,r-1,c,visit)+
countingSteps(limit,rows,cols,r,c+1,visit)+
countingSteps(limit,rows,cols,r,c-1,visit)+1;
}
private int bitSum(int i){
int count = 0;
while( i > 0){
count += i % 10;
i = i / 10;
}
return count;
}
//方法二:使用非递归DFS求解
//需要记录已经遍历过的节点,用辅助矩阵visit[rows * cols]
public int movingCount(int threshold, int rows, int cols){
if(rows <= 0 || cols <= 0 || threshold < 0) return 0;
boolean [] visit = new boolean [rows*cols]; //为了配合栈使用
Stack <Integer> s = new Stack <Integer> ();
int[][] xoy = {{0,1,0,-1},{1,0,-1,0}};
int count = 0;
s.push(0);
visit[0] = true;
while(!s.empty()){
int cur = s.pop();
count++ ;
for(int i = 0; i < 4; i++){
int x = cur % cols + xoy[0][i];
int y = cur / cols + xoy[1][i];
if( x>=0 && y>=0 && x<cols && y<rows &&
!visit[x+y*cols] && bitSum(x)+bitSum(y)<=threshold){
s.push(x+y*cols);
visit[x+y*cols] = true;
}
}
return count;
}