LC-695. 岛屿的最大面积

155 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

题目描述

给你一个大小为 m x n 的二进制矩阵 grid 。

岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。

岛屿的面积是岛上值为 1 的单元格的数目。

计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0 。

示例 1:

输入:grid = [[0,0,1,0,0,0,0,1,0,0,0,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,1,1,0,1,0,0,0,0,0,0,0,0],[0,1,0,0,1,1,0,0,1,0,1,0,0],[0,1,0,0,1,1,0,0,1,1,1,0,0],[0,0,0,0,0,0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,0,0,0,0,0,0,1,1,0,0,0,0]]
输出:6
解释:答案不应该是 11 ,因为岛屿只能包含水平或垂直这四个方向上的 1

示例 2:

输入: grid = [[0,0,0,0,0,0,0,0]]
输出: 0

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 50
  • grid[i][j] 为 0 或 1

题解

这道题,首先必须是两层循环,进行查找值为1的下标 x和y。

找到后,我们先将该值进行标记,之后进行 广度或者深度优先遍历的方式 来查找当前与之连接的为1的其他值,并进行再次标记,并记录当前岛屿的长度,直到结束。

最终进行比较得到最大的值。

1.bfs 广度优先遍历

const maxAreaOfIsland = (grid) => {
  const returnValue = (x, y) => {
    return grid[x][y]
  }

  const isExistence = (x, y) => {
    if (x >= rowLength || y >= columnLength || x < 0 || y < 0) return false
    return true
  }

  const positionTop = (x, y) => {
    return [x - 1, y]
  }
  const positionBottom = (x, y) => {
    return [x + 1, y]
  }
  const positionLeft = (x, y) => {
    return [x, y - 1]
  }
  const positionRight = (x, y) => {
    return [x, y + 1]
  }

  const breadthFunc = (x, y) => {
    const bfs = [[x, y]]
    let count = 0

    // 1~3
    while (bfs.length) {
      const [x, y] = bfs.shift()

      if (!isExistence(x, y)) continue

      const val = returnValue(x, y)

      if (val === 0 || val === 2) continue

      grid[x][y] = 2
      count += 1

      bfs.push(positionTop(x, y))
      bfs.push(positionBottom(x, y))
      bfs.push(positionLeft(x, y))
      bfs.push(positionRight(x, y))
    }

    return count
  }

  const rowLength = grid.length
  const columnLength = grid[0].length
  let max = 0

  for (let i = 0; i < rowLength; i++) {
    for (let j = 0; j < columnLength; j++) {
      if (grid[i][j] === 1) {
        max = Math.max(max, breadthFunc(i, j))
      }
    }
  }
  return max
}

1.dfs 深度优先遍历

const maxAreaOfIsland = (grid) => {
  const returnValue = (x, y) => {
    return grid[x][y]
  }

  const isExistence = (x, y) => {
    if (x >= rowLength || y >= columnLength || x < 0 || y < 0) return false
    return true
  }

  const positionTop = (x, y) => {
    return [x - 1, y]
  }
  const positionBottom = (x, y) => {
    return [x + 1, y]
  }
  const positionLeft = (x, y) => {
    return [x, y - 1]
  }
  const positionRight = (x, y) => {
    return [x, y + 1]
  }

  const depthFunc = (x, y) => {
    if (!isExistence(x, y)) return

    const val = returnValue(x, y)

    if (val === 0 || val === 2) return

    grid[x][y] = 2
    maxList[index] ? (maxList[index] += 1) : (maxList[index] = 1)

    depthFunc(...positionTop(x, y))
    depthFunc(...positionBottom(x, y))
    depthFunc(...positionLeft(x, y))
    depthFunc(...positionRight(x, y))
  }

  const rowLength = grid.length
  const columnLength = grid[0].length
  const maxList = []
  let index = -1

  for (let i = 0; i < rowLength; i++) {
    for (let j = 0; j < columnLength; j++) {
      if (grid[i][j] === 1) {
        index += 1
        depthFunc(i, j)
      }
    }
  }
  return maxList.length ? Math.max(...maxList) : 0
}

总结

题目 11 :该题目虽然 进行了双层for循环遍历,看似逻辑很复杂,实际上去理一理还是很好理解,还是用到了广度和深度优先遍历。