題目描述
地上有一個m行和n列的方格。一個機器人從座標0,0的格子開始移動,每一次只能向左,右,上,下四個方向移動一格,但是不能進入行座標和列座標的數位之和大於k的格子。 例如,當k爲18時,機器人能夠進入方格(35,37),因爲3+5+3+7 = 18。但是,它不能進入方格(35,38),因爲3+5+3+8 = 19。請問該機器人能夠達到多少個格子?
解題思路
這個方格也可以看出一個 m*n 的矩陣。同樣在這個矩陣中,除邊界上的格子之外其他格子都有四個相鄰的格子。
機器人從座標(0,0)開始移動。當它準備進入座標爲(i,j)的格子時,通過檢查座標的數位和來判斷機器人是否能夠進入。如果機器人能夠進入座標爲(i,j)的格子,我們接着再判斷它能否進入四個相鄰的格子(i,j-1)、(i-1,j),(i,j+1) 和 (i+1,j)。
程序實現
public class Solution {
public int movingCount(int threshold, int rows, int cols)
{
// 參數校驗
if (threshold < 0 || rows < 1 || cols < 1) {
return 0;
}
// 變量初始化
boolean[] visited = new boolean[rows * cols];
for (int i = 0; i < visited.length; i++) {
visited[i] = false;
}
return movingCountCore(threshold,rows,cols,0,0,visited);
}
/**
* 遞歸回溯方法
*
* @param threshold 約束值
* @param rows 方格的行數
* @param cols 方格的列數
* @param row 當前處理的行號
* @param col 當前處理的列號
* @param visited 訪問標記數組
* @return 最多可走的方格
*/
private int movingCountCore(int threshold, int rows, int cols,
int row, int col, boolean[] visited) {
int count = 0;
if (check(threshold, rows, cols, row, col, visited)) {
visited[row * cols + col] = true;
count = 1
+ movingCountCore(threshold, rows, cols, row - 1, col, visited)
+ movingCountCore(threshold, rows, cols, row, col - 1, visited)
+ movingCountCore(threshold, rows, cols, row + 1, col, visited)
+ movingCountCore(threshold, rows, cols, row, col + 1, visited);
}
return count;
}
/**
* 斷機器人能否進入座標爲(row, col)的方格
*
* @param threshold 約束值
* @param rows 方格的行數
* @param cols 方格的列數
* @param row 當前處理的行號
* @param col 當前處理的列號
* @param visited 訪問標記數組
* @return 是否可以進入,true是,false否
*/
private boolean check(int threshold, int rows, int cols,
int row, int col, boolean[] visited) {
return col >= 0 && col < cols
&& row >= 0 && row < rows
&& !visited[row * cols + col]
&& (getDigitSum(col) + getDigitSum(row) <= threshold);
}
/**
* 一個數字的數位之和
*
* @param number 數字
* @return 數字的數位之和
*/
private int getDigitSum(int number) {
int result = 0;
while (number > 0) {
result += (number % 10);
number /= 10;
}
return result;
}
}