美文网首页
Python LeetCode-200.数据结构 岛屿的个数 深

Python LeetCode-200.数据结构 岛屿的个数 深

作者: Jayce_xi | 来源:发表于2019-04-04 14:36 被阅读0次

在做这个题目的时候,可以先看下这篇文章python-数据结构 队列和广度优先搜索(BFS)

1.题目 岛屿的个数

给定一个由 "1"(陆地)和 "0"(水)组成的的二维网格(这里要注意 "1""0"都是字符串),计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。

Given a 2d grid map of "1" is (land) and "0"s (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

2. 示例

Example 1:
Input:
11110
11010
11000
00000
Output: 1

Example 2:
Input:
11000
11000
00100
00011
Output: 3

2.三种结题方式

1.广度优先 (非递归的方式)其中有队列思想

参考出处
思路:

  • 先看代码再看思路,这一版是参考别人的,下面有优化版。
  • 利用一个mark二位数组,标记已经被认定为岛屿的点,这些点就不会再去计数。
  • 利用一个列表来做一个先进先出的队列,广度优先的寻找为"1"的点,将这些点都标记为False
  • 广度优先查找的感觉类似这样
  • 可以参考我的这篇文章,来理解队列在广度优先查找中的思想python-数据结构 队列和广度优先搜索(BFS)或者我的博客看看
class Solution:
    # @param {boolean[][]} grid a boolean 2D matrix
    # @return {int} an integer
    def numIslands(self, grid):
        # 特殊值检错
        if not grid:
            return 0
        if isinstance(grid[0], bool) or isinstance(grid[0], int):
            return 1 if grid[0] else 0
        # Write your code here
        count = 0  # 计数
        # 行列数
        m, n = len(grid), len(grid[0])
        # 标记初始为True 扩展到的为False不再进行检测
        mark = self._mark(m, n)
        for i in range(m):
            for j in range(n):
                if grid[i][j] == "1":
                    if mark[i][j]:  # 检查标记
                        count += 1
                        mark[i][j] = False
                        self._expand(i, j, grid, mark)
        return count

    @staticmethod
    def _mark(m, n):
        mark = []
        for i in range(m):
            mark.append([True] * n)
        return mark

    @staticmethod
    def _expand(i, j, grid, mark):
        # 向右向下扩展,广度优先,利用队列,进行广度优先查询
        t = [(i, j)]
        # 用于检查边界
        m, n = len(grid), len(grid[0])
        while len(t) != 0:
            i, j = t.pop()
            # 左
            if i > 0:
                if mark[i - 1][j]:
                    if grid[i - 1][j] == "1":
                        mark[i - 1][j] = False
                        t.append((i - 1, j))
            # 右
            if i < m - 1:
                if mark[i + 1][j]:
                    if grid[i + 1][j] == "1":
                        mark[i + 1][j] = False
                        t.append((i + 1, j))

            # 上
            if j > 0:
                if mark[i][j - 1]:
                    if grid[i][j - 1] == "1":
                        mark[i][j - 1] = False
                        t.append((i, j - 1))

            # 下
            if j < n - 1:
                if mark[i][j + 1]:
                    if grid[i][j + 1] == "1":
                        mark[i][j + 1] = False
                        t.append((i, j + 1))


if __name__ == '__main__':
    s = Solution()
    g0 = []
    g1 = [["0"]]
    g2 = [["1", "1", "0", "0", "0"],
          ["1", "1", "0", "0", "0"],
          ["0", "0", "1", "0", "0"],
          ["0", "0", "0", "1", "1"]]
    for g in [g0, g1, g2]:
        print(s.numIslands(g))

2.广度优先优化版本(非递归,强调内存的重复利用)

思路

  • 思想是和上一个完全一样的,但是利用了原来grid的数据结构,节约了内存空间,这个思想在LeetCode中的很多题目都会体现,特别是在要求不使用额外的内存的算法题当中,类似这一题-->LeetCode-442-数组中重复的数据(难度-中等)
class Solution:
    # @param {boolean[][]} grid a boolean 2D matrix
    # @return {int} an integer
    def numIslands(self, grid):
        # 特殊值检错
        if not grid:
            return 0
        if isinstance(grid[0], bool) or isinstance(grid[0], int):
            return 1 if grid[0] else 0
        # Write your code here
        count = 0  # 计数
        # 行列数
        m, n = len(grid), len(grid[0])
        for i in range(m):
            for j in range(n):
                if grid[i][j] == "1":
                    count += 1
                    grid[i][j] = "0"
                    self._expand(i, j, grid)
        return count

    @staticmethod
    def _expand(i, j, grid):
        # 向右向下扩展,广度优先
        t = [(i, j)]   # 相当一个先进先出队列,进行广度优先查询
        # 用于检查边界
        m, n = len(grid), len(grid[0])
        while len(t) != 0:
            i, j = t.pop()
            # 左
            if i > 0:
                if grid[i - 1][j] == "1":
                    grid[i - 1][j] = False
                    t.append((i - 1, j))
            # 右
            if i < m - 1:
                if grid[i + 1][j] == "1":
                    grid[i + 1][j] = False
                    t.append((i + 1, j))

            # 上
            if j > 0:
                if grid[i][j - 1] == "1":
                    grid[i][j - 1] = False
                    t.append((i, j - 1))

            # 下
            if j < n - 1:
                if grid[i][j + 1] == "1":
                    grid[i][j + 1] = False
                    t.append((i, j + 1))
        return grid


if __name__ == '__main__':
    s = Solution()
    g0 = []
    g1 = [["0"]]
    g2 = [["1", "1", "0", "0", "0"],
          ["1", "1", "0", "0", "0"],
          ["0", "0", "1", "0", "0"],
          ["0", "0", "0", "1", "1"]]
    for g in [g0, g1, g2]:
        print(s.numIslands(g))

3.深度优先解答(递归)

思路:

  • 先大致浏览下代码再看思路
  • 使用递归的思路,当一个点是"1"标记是岛屿的时候,将这个点置为"0",且将它的上下左右四个点为"1"的也全部置"0",且这四个点的上下左右接着进行查询是否有"1",不断递归下去,直到遇到递归终止条件。
  • 递归的终止条件为i或者j到达边界(i >= len(grid) or j >= len(grid[0]) or i < 0 or j < 0)。递归最重要的就是找终止条件。
class Solution:

    def numIslands(self, grid):
        if grid is None or not grid or len(grid) == 0 or len(grid[0]) == 0:  # 对于特殊值的处理
            return 0
        m = len(grid)
        n = len(grid[0])
        res = 0  # 判定岛屿的数量
        for i in range(m):
            for j in range(n):
                if grid[i][j] == "1":
                    res += 1
                    self.dfs(grid, i, j)
        return res

    def dfs(self, grid, i, j):
        if i >= len(grid) or j >= len(grid[0]) or i < 0 or j < 0:
            return
        if grid[i][j] == "1":
            grid[i][j] = "0"
            self.dfs(grid, i + 1, j)
            self.dfs(grid, i - 1, j)
            self.dfs(grid, i, j + 1)
            self.dfs(grid, i, j - 1)


if __name__ == '__main__':
    s = Solution()
    g0 = []
    g1 = [["0"]]
    g2 = [["1", "1", "0", "0", "0"],
          ["1", "1", "0", "0", "0"],
          ["0", "0", "1", "0", "0"],
          ["0", "0", "0", "1", "1"]]
    for g in [g0, g1, g2]:
        print(s.numIslands(g))

相关文章

  • Python LeetCode-200.数据结构 岛屿的个数 深

    在做这个题目的时候,可以先看下这篇文章python-数据结构 队列和广度优先搜索(BFS) 1.题目 岛屿的个数 ...

  • 岛屿个数

    题目给定一个m行n列的二维地图,初始化每个单元都是水,操作addLand把单元格(row,col)变成陆地。岛屿定...

  • 岛屿的个数

    给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或...

  • 岛屿的个数

    给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或...

  • 岛屿的个数

    这题考察广度优先遍历和深度优先遍历,利用递归的方式做还算比较简单,但是输出的格式有待斟酌! 几个岛(滴滴) 题目:...

  • 岛屿的个数

    题目 思路:搜索到陆地(1)以后向前后以及下方遍历直至搜到海(0),将搜索到的陆地全部置为0并且将岛屿数量+1。

  • 2018-07-31测试1

    2018年7⽉30⽇ 星期⼀Python测试⼀基础部分 Python都有哪些⾃带的数据结构? 给定⼀个数字变量x,...

  • 列表

    Python3 列表 序列是Python中最基本的数据结构。序列中的每个元素都分配一个数字 (这个数字就是它所在的...

  • LeetCode:岛屿的个数

    岛屿的个数 题目叙述: 给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围...

  • Lesson 015 —— python 列表

    Lesson 015 —— python 列表 序列是Python中最基本的数据结构。序列中的每个元素都分配一个数...

网友评论

      本文标题:Python LeetCode-200.数据结构 岛屿的个数 深

      本文链接:https://www.haomeiwen.com/subject/inhfiqtx.html