Leetcode daily 20/03/15 岛屿的最大面积

岛屿的最大面积

-题目-

给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合。你可以假设二维矩阵的四个边缘都被水包围着。
找到给定的二维数组中最大的岛屿面积。(如果没有岛屿,则返回面积为0。)

-示例1-

[[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-

[[0,0,0,0,0,0,0,0]]
对于上面这个给定的矩阵, 返回 0。

-注意-

给定的矩阵grid 的长度和宽度都不超过 50。


-方法1-

  • 把每个岛屿当作一个图。遍历数组,遇到岛屿就深度遍历,找到这个岛屿(图)的节点数。遍历完成后最大节点数就是结果。为了防止重复遍历一个位置,可用一个和输入相同大小的矩阵记录是否访问过。

-ac代码-

class Solution:

    def __init__(self):
        self.maxArea = 0
        self.currArea = 0

        self.grid = None
        self.visited = None

        self.height = 0
        self.width = 0

    def search(self, i, j):
        # The idxs should be greater than 0 since negative idxs are valid for python.
        if not (0 <= i < self.height and 0 <= j < self.width):
            return
        # The element should be 1 and the loc should not be visited.
        if not (self.grid[i][j] == 1 and self.visited[i][j] == 0):
            return

        # Not visited -> visited.
        self.visited[i][j] = 1
        self.currArea += 1

        # >
        self.search(i + 1, j)
        # <
        self.search(i - 1, j)
        # v
        self.search(i, j + 1)
        # ^
        self.search(i, j - 1)

    def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
        # Init for some vars.
        self.grid = grid
        self.height = len(grid)
        self.width = len(grid[0])

        # Creates a matrix with the same size as `grid` to track if the loc is visited.
        self.visited = copy.deepcopy(self.grid)
        for i in range(self.height):
            for j in range(self.width):
                self.visited[i][j] = 0

        for i in range(self.height):
            for j in range(self.width):
                # If the element is 1 and the loc is not visited.
                if self.grid[i][j] == 1 and self.visited[i][j] == 0:
                    self.search(i, j)

                self.maxArea = max(self.maxArea, self.currArea)

                self.currArea = 0

        return self.maxArea

-复杂度-

  • \(T(n) = O(height * width)\) (每个节点最多访问一次)
  • \(S(n) = O(height * width + height + width)\) (递归需要栈,最大栈为输入的大小;记录是否访问的数组和输入一样大)

-方法1笔记-

  • grid的下标应该大于0。这是因为负数下标是合法的,但对应的元素可能是当前岛屿之外的某一个位置。
  • 如果某个位置的1未被访问,该位置被访问后其上下左右都要被访问,而不是只有右边和下边。
  • 记录当前岛屿节点数的currArea在当前岛屿被计算完后需置0。

-方法1·改-

  • 和的方法1基本相同,但不用额外的数组记录是否被访问,而是将访问过的元素置0。还修改了当前岛屿面积和最大岛屿面积的方法,使search()函数返回当前岛屿的值。

-ac代码-

class Solution:

    def __init__(self):
        self.grid = None

        self.height = 0
        self.width = 0

    def search(self, i, j):
        # The idxs should be greater than 0 since negative idxs are valid for python.
        if not (0 <= i < self.height and 0 <= j < self.width):
            return 0
        # The element should be 1.
        if not (self.grid[i][j] == 1):
            return 0

        self.grid[i][j] = 0

        return (1
            + self.search(i + 1, j)
            + self.search(i - 1, j)
            + self.search(i, j + 1)
            + self.search(i, j - 1))

    def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
        # Init for some vars.
        self.grid = grid
        self.height = len(grid)
        self.width = len(grid[0])

        max_area = 0
        for i in range(self.height):
            for j in range(self.width):
                # If the element is 1.
                if self.grid[i][j] == 1:                
                    max_area = max(max_area, self.search(i, j))

        return max_area

-复杂度-

  和方法一相同。

上一篇:[Daily Practice] -接雨水问题


下一篇:在线教育项目-day17【统计图表前端整合】