代码随想录算法训练营第52天| 101. 孤岛的总面积、102. 沉没孤岛、103. 水流问题、104.建造最大岛屿

101. 孤岛的总面积

卡码题目链接:101. 孤岛的总面积

学习链接:代码随想录

题解:

法一:

count = 0
def dfs(grid,x,y):
    global count
    grid[x][y] = 0
    count += 1
    directions = [[1,0],[0,1],[-1,0],[0,-1]]
    for i,j in directions:
        next_x = x+i
        next_y = y+j
        if next_x < 0 or next_x >= len(grid) or next_y < 0 or next_y >= len(grid[0]):
            continue
        if grid[next_x][next_y] == 1:
            dfs(grid,next_x,next_y)


def main():
    # 因为这边不把count变成全局变量的话 count始终是初始化的0 不会有改变
    global count
    n,m = map(int,input().split())
    grid = []
    for _ in range(n):
        grid.append(list(map(int,input().split())))
        
    for i in range(n):
        if grid[i][0] == 1:
            dfs(grid,i,0)
        if grid[i][m - 1] == 1: 
            dfs(grid, i, m - 1)
    for j in range(m):
        if grid[0][j] == 1:
            dfs(grid,0,j)
        if grid[n - 1][j] == 1: 
            dfs(grid, n - 1, j)
    count = 0
    
    for i in range(n):
        for j in range(m):
            if grid[i][j] == 1:
                dfs(grid,i,j)
    
    print(count)
    
if __name__ == "__main__":
    main()

Global变量使用:

x = 10  # 全局变量

def modify():
    global x  # 声明 x 是全局变量
    x = 20  # 修改全局变量 x
    print("Inside function:", x)

modify()
print("Outside function:", x)

x可被修改 

x = 10  # 全局变量

def modify():
    x = 20  # 这里创建了一个局部变量 x
    print("Inside function:", x)

modify()
print("Outside function:", x)

x不可被修改 


102. 沉没孤岛

卡码题目链接:102. 沉没孤岛

学习链接:代码随想录

题解:

法一:

def dfs(grid,x,y):
    grid[x][y] = 2
    directions = [[1,0],[0,1],[-1,0],[0,-1]]
    for i,j in directions:
        next_x = x+i
        next_y = y+j
        if next_x < 0 or next_x >= len(grid) or next_y < 0 or next_y >= len(grid[0]):
            continue
        if grid[next_x][next_y] == 2 or grid[next_x][next_y] == 0:
            continue
        dfs(grid,next_x,next_y)

def main():
    n,m = map(int,input().split())
    grid = []
    for _ in range(n):
        grid.append(list(map(int,input().split())))
    
    for i in range(n):
        if grid[i][0] == 1:
            dfs(grid,i,0)
        if grid[i][m-1] == 1:
            dfs(grid,i,m-1)
    for j in range(m):
        if grid[0][j] == 1:
            dfs(grid,0,j)
        if grid[n-1][j] == 1:
            dfs(grid,n-1,j)
    
    for i in range(n):
        for j in range(m):
            if grid[i][j] == 2:
                grid[i][j] = 1
            elif grid[i][j] == 1:
                grid[i][j] = 0
    
    for row in grid:
        print(" ".join(map(str,row)))

if __name__ == "__main__":
    main()

思路有点难 先把边上不是孤岛的转为2 然后再检查是2的变为1 是1的变为0


103. 水流问题

卡码题目链接:103. 水流问题

学习链接:代码随想录

题解:

法一:

first = set()
second = set()
def dfs(x,y,grid,visited,group):
    if visited[x][y]:
        return
    directions = [[1,0],[0,1],[-1,0],[0,-1]]
    visited[x][y] = True
    group.add((x,y))
    for i,j in directions:
        next_x = x+i
        next_y = y+j
        if (0 <= next_x < len(grid)) and (0 <= next_y < len(grid[0])) and grid[next_x][next_y] >= grid[x][y]:
            dfs(next_x,next_y,grid,visited,group)

def main():
    global first
    global second
    n,m = map(int,input().split())
    
    grid = []
    for _ in range(n):
        grid.append(list(map(int,input().split())))
    
    visited = [[False] * m for _ in range(n)]
    for i in range(n):
        dfs(i,0,grid,visited,first)
    for j in range(m):
        dfs(0,j,grid,visited,first)
    
    visited = [[False] * m for _ in range(n)]
    for i in range(n):
        dfs(i,m-1,grid,visited,second)
    for j in range(m):
        dfs(n-1,j,grid,visited,second)
    # 取并集的写法
    res = first.intersection(second)
    
    for i,j in res:
        print(f"{i} {j}")

if __name__ == "__main__":
    main()
        

一个反转是把从高到低找边界 变成边界从低找高处

然后把边界分为左上和右下两部分 各自找到之后取相交。


104.建造最大岛屿

卡码题目链接:104. 建造最大岛屿

乐扣题目链接:827. 最大人工岛 - 力扣(LeetCode)

学习链接:​​​​​​​代码随想录

题解:

卡码:

from collections import defaultdict
directions = [[1,0],[0,1],[-1,0],[0,-1]]

def dfs(grid,visited,x,y,num):
    if visited[x][y]:
        return
    
    area = 1
    visited[x][y] = True
    grid[x][y] = num
    
    for i,j in directions:
        next_x = x+i
        next_y = y+j
        if (0 <= next_x < len(grid)) and (0 <= next_y < len(grid[0])) and grid[next_x][next_y] == "1":
            area += dfs(grid,visited,next_x,next_y,num)
    return area
    
def main():
    n,m = map(int, input().strip().split())
    
    grid = []
    for _ in range(n):
        grid.append(input().strip().split())
    
    visited = [[False] * m for _ in range(n)]
    rec = defaultdict(int)
    
    # 编号
    cnt = 2
    for i in range(n):
        for j in range(m):
            if grid[i][j] == "1":
                area = 0
                rec[cnt] = dfs(grid,visited,i,j,cnt)
                cnt += 1
                
    res = 0
    for i in range(n):
        for j in range(m):
            if grid[i][j] == "0":
                max_island = 1
                v = set()
                for dx,dy in directions:
                    next_x = i+dx
                    next_y = j+dy
                    if (0 <= next_x < len(grid)) and (0 <= next_y < len(grid[0])) and grid[next_x][next_y] != "0" and grid[next_x][next_y] not in v:
                        max_island += rec[grid[next_x][next_y]]
                        v.add(grid[next_x][next_y])
                res = max(res,max_island)
    if res == 0:
        res = max(rec.values()) if rec else 0
    
    print(res)
if __name__ == "__main__":
    main()
   

注意area的取值问题 是否能取到

这题太难了 好复杂 要操作的东西很多。

乐扣题解:

import collections
directions = [[-1, 0], [0, 1], [0, -1], [1, 0]]
class Solution:
    def dfs(self,grid,visited,x,y,num):
        if visited[x][y]:
            return 0
        
        visited[x][y] = True
        area = 1
        grid[x][y] = num

        for i,j in directions:
            next_x = i + x 
            next_y = j + y 
            if 0 <= next_x < len(grid) and 0 <= next_y < len(grid[0]) and grid[next_x][next_y] == 1:
                area += self.dfs(grid,visited,next_x,next_y,num)
        return area

    def largestIsland(self, grid: List[List[int]]) -> int:
        visited = [[False] * len(grid[0]) for _ in range(len(grid))]
        rec = collections.defaultdict(int)

        cnt = 2
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == 1:
                    area = 0
                    rec[cnt] = self.dfs(grid,visited,i,j,cnt)
                    cnt += 1
        res = 0
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == 0:
                    max_island = 1
                    v = set()
                    for dx,dy in directions:
                        next_x = dx+i
                        next_y = dy+j
                        if 0 <= next_x < len(grid) and 0 <= next_y < len(grid[0]) and grid[next_x][next_y] != 0 and grid[next_x][next_y] not in v:
                            v.add(grid[next_x][next_y])
                            max_island += rec[grid[next_x][next_y]]
                    res = max(res,max_island)
        
        if res == 0:
            res = max(rec.values()) if rec else 0
        return res

你可能感兴趣的:(算法,深度优先)