注意深搜的两种写法,熟练掌握这两种写法 以及 知道区别在哪里,才算掌握的深搜。
注意广搜的两种写法,第一种写法为什么会超时, 如果自己做的录友,题目通过了,也要仔细看第一种写法的超时版本,弄清楚为什么会超时,因为你第一次 幸运 没那么想,第二次可就不一定了。
代码随想录
深度搜索,定义上下左右四个方向,找到一个第一个邻接矩阵就递归该点的上下左右,避免重复计算。
版本一:
direction=[[0,1],[1,0],[0,-1],[-1,0]]
def dfs(grid,visited,x,y):
for i,j in direction:
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 not visited[next_x][next_y] and grid[next_x][next_y]==1:
visited[next_x][next_y]=True
dfs(grid,visited,next_x,next_y)
if __name__=='__main__':
n,m=map(int,input().split())
grid=[]
for i in range(n):
grid.append(list(map(int,input().split())))
visited=[[False]*m for _ in range(n)]
res=0
for i in range(n):
for j in range(m):
if grid[i][j]==1 and not visited[i][j]:
res+=1
visited[i][j]=True
dfs(grid,visited,i,j)
print(res)
版本二:
direction=[[0,1],[1,0],[0,-1],[-1,0]]
def dfs(grid,visited,x,y):
if visited[x][y] or grid[x][y]==0:
return
visited[x][y]=True
for i,j in direction:
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 not visited[next_x][next_y] and grid[next_x][next_y]==1:
# visited[next_x][next_y]=True
# dfs(grid,visited,next_x,next_y)
dfs(grid,visited,next_x,next_y)
if __name__=='__main__':
n,m=map(int,input().split())
grid=[]
for i in range(n):
grid.append(list(map(int,input().split())))
visited=[[False]*m for _ in range(n)]
res=0
for i in range(n):
for j in range(m):
if grid[i][j]==1 and not visited[i][j]:
res+=1
#visited[i][j]=True
dfs(grid,visited,i,j)
print(res)
版本一的写法是 :下一个节点是否能合法已经判断完了,传进dfs函数的就是合法节点。
版本二的写法是:不管节点是否合法,上来就dfs,然后在终止条件的地方进行判断,不合法再return。
理论上来讲,版本一的效率更高一些,因为避免了 没有意义的递归调用,在调用dfs之前,就做合法性判断。 但从写法来说,可能版本二 更利于理解一些。(不过其实都差不太多)
广度搜索,用队列先进先出来实现广度,横向扩展
from collections import deque
direction=[[0,1],[1,0],[0,-1],[-1,0]]
def bfs(grid,visited,x,y):
que=deque([])
que.append([x,y])
visited[x][y]=True
while que:
cur_x,cur_y=que.popleft()
for i,j in direction:
next_x=cur_x+i
next_y=cur_y+j
if next_x<0 or next_x>=len(grid) or next_y<0 or next_y>=len(grid[0]):
continue
if not visited[next_x][next_y] and grid[next_x][next_y]==1:
visited[next_x][next_y]=True
que.append([next_x,next_y])
if __name__=='__main__':
n,m=map(int,input().split())
grid=[]
for i in range(n):
grid.append(list(map(int,input().split())))
visited=[[False]*m for _ in range(n)]
res=0
for i in range(n):
for j in range(m):
if grid[i][j]==1 and not visited[i][j]:
res+=1
#visited[i][j]=True
bfs(grid,visited,i,j)
print(res)
本题就是基础题了,做过上面的题目,本题很快。代码随想录
增加一个数组用来存放每块岛屿面积,结果输出最大面积
direction=[[0,1],[0,-1],[1,0],[-1,0]]
def dfs(grip,visited,x,y,count,res):
for i,j in direction:
next_x=x+i
next_y=y+j
if next_x<0 or next_x>=len(grip) or next_y<0 or next_y>=len(grip[0]):
continue
if not visited[next_x][next_y] and grip[next_x][next_y]==1:
visited[next_x][next_y]=True
res[count]+=1
dfs(grip,visited,next_x,next_y,count,res)
if __name__=='__main__':
n,m=map(int,input().split())
grip=[]
for i in range(n):
grip.append(list(map(int,input().split())))
visited=[[False]*m for _ in range(n)]
res=[0]*(m*n)
count=0
for i in range(n):
for j in range(m):
if grip[i][j]==1 and not visited[i][j]:
visited[i][j]=True
count+=1
res[count]+=1
dfs(grip,visited,i,j,count,res)
print(max(res))