正确处理一个矩阵

在处理一个矩阵 matrix[][] 时,虽然很清楚接下来该怎么做,但最后的结果往往会报数组越界的错误,致使编程5分钟,排错2小时,极其浪费时间。

究其原因,是没有理清矩阵与二维数组的对应关系,甚至与坐标轴混淆,且听我一点一点分析。

首先,我们需要创建一个二维数组 arr 来存储一个m*n的矩阵 matrix,有多种方法可以参考前文 Javascript的一些坑点,这里使用es6的简介写法

let arr = new Array(m).fill(0).map(v => new Array(n).fill(0));

matrix 与 arr 的第一个对应关系:

matix为m行n列的矩阵:则

arr.length === m

arr[0].length === n

这个很好理解

然后,我们可以用 arr[x][y] 保存当前矩阵的元素,但是这样做极其容易出错,出错的原因是会与坐标轴的混淆

arr[x][y] 在矩阵上 是 第x行第y列的元素,在坐标轴上 是 (y, x)

x的范围为 0<=x<n

y的范围为 0<=y<m

因此在实际编程中,受坐标系的影响往往会写出以下代码,导致数组越界:

while(x>=0 || x<列数 || y>=0 || y<行数)

所以,如果你如果实在摆脱不了坐标轴的影响,你可以这样定义遍历中的矩阵元素:arr[y][x] 上述问题即可解决,只不过写起来读起来会比较变扭

总结下写法,定义 x,y 分别为 arr 的 行号,列号,则
0<=x<arr.length

0<=y<arr[0].length

使用元素便能直接用 arr[x][y] 了

let arr = matrix;
let m = matix.length, n = matrix[0].length;
let x = 0, y = 0;
while(x>=0 || x<n || y>=0 || y<m) {
	arr[x][y]
}

这样写就一点问题就没了

拿一道BFS的题来验证下:
在这里插入图片描述

/**
 * @param {character[][]} maze
 * @param {number[]} entrance
 * @return {number}
 */
/**
 * @param {character[][]} maze
 * @param {number[]} entrance
 * @return {number}
 */
var nearestExit = function(maze, entrance) {
    let [U, L, D, R] = [ [-1,0], [0,-1], [1,0], [0,1] ];
    let queue = [];
    let m = maze.length, n = maze[0].length;
    queue.unshift(entrance);
    maze[entrance[0]][entrance[1]] = '+';
    let res = 0;
    while(queue.length !== 0) {
        let tmp = [];
        res++;
        while(queue.length !== 0) {
            let [x0, y0] = queue.pop();
            for(let [dx, dy] of [U, L, D, R]) {
                let x = x0+dx;
                let y = y0+dy;
                if(x<0 || x>m-1 || y<0 || y>n-1) continue;
                if(maze[x][y] === ".") {
                    if(x===0 || x===m-1 || y===0 || y===n-1) return res;
                    else {
                        maze[x][y] = '+';
                        tmp.unshift([x,y]);
                    }
                }
            }
        }
        queue = tmp;
    }
    return -1;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值