演算法-機器人的運動範圍

JayJunG發表於2019-01-10

題目描述

地上有一個 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;
}
複製程式碼


相關文章