题目描述
地上有一个 m 行和 n 列的方格。一个机器人从坐标 (0, 0) 的格子开始移动,每一次只能向左右上下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于 k 的格子。
例如,当 k 为 18 时,机器人能够进入方格 (35,37),因为 3+5+3+7=18。但是,它不能进入方格 (35,38),因为 3+5+3+8=19。请问该机器人能够达到多少个格子?
解题思路
回溯法
核心思路:
1.从(0,0)开始走,每成功走一步标记当前位置为true,然后从当前位置往四个方向探索,
返回1 + 4 个方向的探索值之和。
2.探索时,判断当前节点是否可达的标准为:
1)当前节点在矩阵内;
2)当前节点未被访问过;
3)当前节点满足limit限制。
let next = [[0,-1],[0,1],[-1,0],[1,0]]; //作为方向
let sum = 0;
let rows = 0,cols = 0;
let k, digitSum;
let dfs = function dfs(marked, r, c){
if(r<0||r>=rows||c<0||c>cols||marked[r][c]){
return;
}
marked[r][c] = true;
if(digitSum[r][c]>k){
return;
}
sum++;
for(let n of next){
dfs(marked, r+n[0], c+n[1]);
}
}
let initDigitSum = function initDigitSum(){
let digitSumOne = new Array(Math.max(cols,rows));
for(let i = 0,len = digitSumOne.length;i<len;i++){
let n = i;
while(n>0){
digitSumOne[i] += n%10;
n = Math.floor(n/10);
}
}
digitSum = new Array(rows).fill(new Array(cols));
for(let i = 0;i<rows;i++){
for(let j = 0;j<cols;j++){
digitSum[i][j] = digitSum[i] + digitSum[j];
}
}
}
//主函数
let movingCount = function(threshold, row, col){
rows = rows;
cols = cols;
k = threshold;
initDigitSum(); //初始化坐标数位和二维数组
let marked = new Array(rows).fill(new Array(cols).fill(false)); //标志路径,走过的记为true
dfs(marked,0,0); //回溯求最大值
return sum;
}