这道题和其它的islands题目非常类似。难点在于如何确定两个islands之间的最短距离。 最直接的想法是:

  • dfs把两个islands的坐标分别记录下来,存在两个array中。
  • 双重循环两个array, 找到其中Manhattan距离最短的两个点。
  • 这种方法勉强AC, beat 0% (囧)
var shortestBridge = function(grid) {
    const rows = grid.length;
    if (rows === 0) {
        return 0;
    }
    const cols = grid[0].length;

    const islands = [];
    for (let i = 0; i < rows; i++) {
        for (let j = 0; j < cols; j++) {
            if (grid[i][j] === 1) {
                islands.push(dfs(i, j, grid));
            }
        }
    }
    const land1 = islands[0];
    const land2 = islands[1];

    let res = rows + cols;
    for (let i = 0; i < land1.length; i++) {
        for (let j = 0; j < land2.length; j++) {
            res = Math.min(res,  dist(land1[i], land2[j]) - 1);
        }
    }
    return res;   
};

function dist(p1, p2) {
    return Math.abs(p1[0] - p2[0]) + Math.abs(p1[1] - p2[1]);
}


function dfs(row, col, grid) {
    const rows = grid.length;
    const cols = grid[0].length;
    grid[row][col] = 0;
    const dx = [0, 1, 0, -1];
    const dy = [1, 0, -1, 0];
    let arr = [[row, col]];
    for (let i = 0; i < 4; i++) {
        const nextRow = dx[i] + row;
        const nextCol = dy[i] + col;
        if (nextRow >= 0 && nextRow < rows && nextCol >= 0 && nextCol < cols && grid[nextRow][nextCol] === 1) {
            arr = [...arr, ...dfs(nextRow, nextCol, grid)];
        }
    }
    return arr;
}

更好的做法是:

  • dfs找到一个island的所有点
  • 用bfs从所有点向外扩张,直到碰到第二个island的点
var shortestBridge = function(grid) {
    const rows = grid.length;
    if (rows === 0) {
        return 0;
    }
    const cols = grid[0].length;

    let queue;
    let flag = true;
    for (let i = 0; i < rows && flag; i++) {
        for (let j = 0; j < cols && flag; j++) {
            if (grid[i][j] === 1) {
                queue = dfs(i, j, grid);
                flag = false;
                break;
            }
        }
    }
    let dist = 0;
    const dx = [0, 1, 0, -1];
    const dy = [1, 0, -1, 0];
    while (queue.length > 0) {
        const size = queue.length;
        for (let i = 0; i < size; i++) {
            const [x, y] = queue.pop();
            grid[x][y] = -1;
            for (let j = 0; j < 4; j++) {
                if (x+dx[j] >= 0 && x+dx[j] < rows && y+dy[j] >= 0 && y+dy[j] < cols && grid[x+dx[j]][y+dy[j]] !== -1) {
                    if (grid[x+dx[j]][y+dy[j]] === 1) {
                        return dist;
                    }
                    queue.unshift([x+dx[j], y+dy[j]]);
                }
            }
        }
        dist++;
    }
    return dist;    
};

function dfs(row, col, grid) {
    const rows = grid.length;
    const cols = grid[0].length;
    grid[row][col] = 0;
    const dx = [0, 1, 0, -1];
    const dy = [1, 0, -1, 0];
    let arr = [[row, col]];
    for (let i = 0; i < 4; i++) {
        const nextRow = dx[i] + row;
        const nextCol = dy[i] + col;
        if (nextRow >= 0 && nextRow < rows && nextCol >= 0 && nextCol < cols && grid[nextRow][nextCol] === 1) {
            arr = [...arr, ...dfs(nextRow, nextCol, grid)];
        }
    }
    return arr;
}

results matching ""

    No results matching ""