刷题 | LeetCode200岛屿数量

题目是这样的:
在这里插入图片描述
其实看到这个题目就想到在图像分割中用到的一些算法,有点区域生长的意思,所以初步的思路就是像图像分割那样把每个独立块的1用不同的label贴上,最后label有几个,岛屿就有几个。
然后仔细深入这个想法,首先从图像上一个没有label的点出发贴上label,搜索其四领域,是1则贴上相同label,再对这些贴上label的点搜索四领域,直到一片搜索完成。
这里有两点。
1.怎样完成迭代搜索这个动作?-- 用队列。
2.标记一块搜索完成? – 队列空。

到这里其实就能发现,这里的搜索对应的是一个深度优先搜索,而且并不需要不同的label来标记,只需要记录需要几次能够将所有的1遍历到。
所以进一步的想法是:用一个同大小的矩阵,记作label矩阵,其中为0表示没有遍历到,为1则为遍历到。
那整个算法的流程就是:
1.先把label矩阵中对应原矩阵中的0处标记为1,因为0不需要遍历。
2.一个while循环,当label矩阵中还存在0时,重复动作:找一个岛+计数器++。
3.找一个岛具体为:从label矩阵中一个为0的点出发,标记它为1,在原矩阵中搜索四领域,将为1的点入队,然后它本身出队,重复直到队空。(深度优先搜索)

具体代码如下:

def numIslands(grid):
    h = len(grid[0]) # 列
    w = len(grid) # 行
    '''
    这里w和h的定义有些混淆,按英文意应该互换
    '''
    #print("**",w,"**",h)
    island_num = 0
    # get the label list to mark the already get one
    label = []
    for i in range(w*h):
        label.append(0)

    # firstly we set the 0s marked coz they don't need to find
    for i in range(w):
        for j in range(h):
            if grid[i][j] == 0:
                label[i*h+j] = 1
    # print(label)
    while(label.count(0)!=0):
        # find an island and mark it in label
        FindAnIsland(grid,label,w,h)

        island_num+=1
    
    return island_num
    

def FindAnIsland(islandmap,label,w,h):
    stack = []
    start = label.index(0)
    label[start] = 1
    i = int(start/h)
    j = start%h
    stack.append(i)
    stack.append(j)
    # 深度优先搜索    
    while(stack != []):
        #up
        if stack[0] == 0:
            pass
        else:
            if islandmap[stack[0]-1][stack[1]] == 1 and label[(stack[0]-1)*h+stack[1]] == 0:
                label[(stack[0]-1)*h+stack[1]] = 1
                stack.append(stack[0]-1)
                stack.append(stack[1])
        #down
        if stack[0]+1 == w:
            pass
        else:
            if islandmap[stack[0]+1][stack[1]] == 1 and label[(stack[0]+1)*h+stack[1]] == 0:
                label[(stack[0]+1)*h+stack[1]] = 1
                stack.append(stack[0]+1)
                stack.append(stack[1])
        #right
        if stack[1]+1 == h:
            pass
        else:
            if islandmap[stack[0]][stack[1]+1] == 1 and label[(stack[0])*h+stack[1]+1] == 0:
                label[(stack[0])*h+stack[1]+1] = 1
                stack.append(stack[0])
                stack.append(stack[1]+1)
        #left
        if stack[1] == 0:
            pass
        else:
            if islandmap[stack[0]][stack[1]-1] == 1 and label[(stack[0])*h+stack[1]-1] == 0:
                label[(stack[0])*h+stack[1]-1] = 1
                stack.append(stack[0])
                stack.append(stack[1]-1)
        # print(stack)
        # print('-----')
        stack.pop(0)
        stack.pop(0)










if __name__ == "__main__":
    a = []
    for i in range(3):
        a.append([])
        for j in range(3):
            a[i].append(eval(input("0 or 1: ")))
    #print(a)

    island = numIslands(a)
    print('There are ',island,'islands.')    

一些细节:
1.堆栈通过python list实现,矩阵是二维list
2.边界条件在代码中有注意。
3.代码运行时,map设置为3x3的(可手动更改,也可以写成输入参数),需自己手动输入0/1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值