算法-机器人的运动范围

801 阅读2分钟

题目描述

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