Leetcode 934 两座岛间的最短距离 疑问

来源:1-5 大厂面试为什么总考算法?

甲骨文_0001

2022-10-25

/**
 * @param {number[][]} grid
 * @return {number}
 */
var shortestBridge = function(grid) {
    const dirs = [[0, 1], [0, -1], [-1, 0], [1, 0]];
    //
    const R = grid.length, C = grid[0].length;
    let visited = []; // 代表是否访问过
    for( let r = 0; r < R; r ++ ){
        visited[r] = [];
        for( let c = 0; c < C; c ++ ){
            visited[r][c] = false;
        } // for c
    } // for r

    let step = 0; // 存放结果最短步数

    let queue = []; // 队列 
    for( let r = 0; r < R; r ++ ){
        for( let c = 0; c < C; c ++ ){

            if( grid[r][c] == 1 && !visited[r][c] ){
                step ++;
                queue.push([r, c]);
                visited[r][c] = true;

                while( queue.length > 0 ){

                    let [nowR, nowC] = queue.shift();
                    for( let i = 0; i < dirs.length; i ++ ){

                        let newR = nowR + dirs[i][0], newC = nowC + dirs[i][1];
                        if( inArea( grid, newR,newC ) && !visited[newR][newC] ){
                            if( grid[newR][newC] == 0 ){ // 水
                                visited[newR][newC] = true;
                                queue.push([newR, newC]);
                            }else if( grid[newR][newC] == 1 ){ // 是另一座岛
                                return step;
                            }
                            
                        } // if inArea

                    } // for dirs


                } // while queue.length

            } // if grid[r][c] == 1

        } // for c
    } // for r

    return 0;
};

function inArea( grid, r, c ){
    const R = grid.length, C = grid[0].length;
    return r >= 0 && r < R && c >= 0 && c < C;
}

老师,934题是求解二维数组中两个岛屿间的最短距离,然后我就用了如上的广度遍历的方法去求,结果存放在step变量中,但是没通过全部用例,我想不出来了。。。。。老师,帮忙看看哈:)
图片描述

===============================================================================
老师,我又改了下,然后报了超时了,是借鉴了官方的题解,
图片描述

/**
 * @param {number[][]} grid
 * @return {number}
 */
 var shortestBridge = function(grid) {
    const dirs = [[0, 1], [0, -1], [-1, 0], [1, 0]];
    //
    const R = grid.length, C = grid[0].length;
    let visited = []; // 代表是否访问过
    for( let r = 0; r < R; r ++ ){
        visited[r] = [];
        for( let c = 0; c < C; c ++ ){
            visited[r][c] = false;
        } // for c
    } // for r

    let step = 0; // 存放结果最短步数

    let queue = []; // 队列
	let island = []; // 第一座岛
    for( let r = 0; r < R; r ++ ){
        for( let c = 0; c < C; c ++ ){

            if( grid[r][c] == 1 && !visited[r][c] ){
                queue.push([r, c]);
                visited[r][c] = true;

				// 先找到第一座岛
				while( queue.length > 0 ){
					let [nowR, nowC] = queue.shift();
					island.push([nowR, nowC]);
					for( let i = 0; i < dirs.length; i ++ ){
						let newR = nowR + dirs[i][0], newC = nowC + dirs[i][1];
						if( inArea( grid, newR, newC ) && !visited[newR][newC] && grid[newR][newC] == 1 ){
							queue.push([newR, newC]);
							visited[newR][newC] = true;
						}
					} // for i
				}

				for( let i = 0; i < island.length; i ++ ){
					queue.push( [...island[i]] );
				} // for i

				step = 0;
				// 再寻找另一座岛
                while( queue.length > 0 ){
                    let sz = queue.length;

					for( let k = 0; k < sz; k ++ ){
						let [nowR, nowC] = queue.shift();

						for( let i = 0; i < dirs.length; i ++ ){
							
							let newR = nowR + dirs[i][0], newC = nowC + dirs[i][1];
							if( inArea( grid, newR,newC ) ){
								if( grid[newR][newC] == 0 ){ // 水
									visited[newR][newC] = true;
									queue.push([newR, newC]);
								}else if( grid[newR][newC] == 1 && !visited[newR][newC] ){ // 是另一座岛
									// alert(1);
									return step;
								}
							} // if inArea

						} // for dirs
					} // for k
					step ++;
                } // while queue.length
				
            } // if grid[r][c] == 1

        } // for c
    } // for r

    return 0;
};

function inArea( grid, r, c ){
    const R = grid.length, C = grid[0].length;
    return r >= 0 && r < R && c >= 0 && c < C;
}
写回答

1回答

liuyubobobo

2022-10-26

你没有通过的这个这个测试用例只有 3*3,是足够小的。


010
000
001


应该返回 2,你的算法返回了 1。


实际跟踪一下,看一下自己的算法为什么返回的是 2?自己的程序怎么计算出的 2?


如果还有问题,请具体说明,具体在你的程序的哪个部分,你认为是正确的,某个变量或者某个语句执行后你认为应该是怎样的,可实际是怎样的,你觉得不应该,和你的思考不符。


继续加油!:)

0
3
甲骨文_0001
回复
liuyubobobo
谢谢老师哈,我自己再整个体会下:)
2022-10-28
共3条回复

玩转算法面试-- Leetcode真题分门别类讲解

课程配套大量BAT面试真题,高频算法题解析,强化训练

7408 学习 · 1150 问题

查看课程