剑指 Offer 13. 机器人的运动范围(1/33)

Posted on 2022-03-27 14:35  AcTourist  阅读(39)  评论(0)    收藏  举报

一、题目

 

二、题目分析

  1.看到这个题目“上,下,左,右" 就联想到 bfs 或 dfs 去解决问题

  2.本题中有四个我们要进行解决的问题:(1)位数和计算 (2)四周方向的遍历 (3)限制的条件 (4)格子数的统计

  (1)位数和的计算:解决方法:转换成字符串,讲数值划分成由位数组成的数组,然后累加每个数的值 或者 利用数学公式来解决:利用取余累加;

  (2)四周方向的遍历:解决方法:利用方位数组来解决,这里需要注意的一点是:方位数组和我们学的x轴y轴不一样,是根据行列的增减来决定方向

  (3)限制的条件:解决方法:第一个边界的限制,第二个下一个移动方向不能大于k,第三个当前位置是否走过

  (4)格子数的统计:解决方法:我们可以利用 set 数据结构来解决 (3)中的第三个问题,然后set可以进行统计,然后输出set.size来计算有多少长度(格子数)

三、代码

/**
 * @param {number} m
 * @param {number} n
 * @param {number} k
 * @return {number}
 */
var movingCount = function(m, n, k) {
    //位数和的计算
    function getsum(num){
        let answer = 0;
        while(num){
            answer += num %10;
            num = Math.floor(num/10);
        }
        return answer;
    }    

    //方向数组
    const directionArry = [
        [-1,0],//向上
        [0,1],//向右
        [1,0],//向下
        [0,-1]//向左
    ];

    //定义set
    let set = new Set(['0,0']);

    //从头开始
    let queue = [[0,0]];
    
    //遍历队列中的坐标
    while(queue.length){
        //移除队列的首坐标
        let [x,y] = queue.shift();
        //遍历方向
        for(let i =0; i<4; i++){
            let setX = x + directionArry[i][0];
            let setY = y + directionArry[i][1];

            if( setX < 0 || setX >=m || setY < 0 || setY >=n || getsum(setX) + getsum(setY) > k || set.has(`${setX},${setY}`) ){
                continue;
            }
            
            set.add(`${setX},${setY}`);
            queue.push([setX,setY]);
        }
    }
    
    return set.size;
};