算法 leetCode 岛屿问题
'''
岛屿数量
问题描述
给定一个有’1‘(陆地)和’0‘组成的二维网格
计算到预计的数量。
一个岛被水包围而成,并且它是通过水平方向相邻的陆地链接而成的
输入:
11110
11010
11000
00000
输出:1
输入
11000
11000
00100
00011
输出 3
'''
# 算法一 深度搜索
lands = 0
def dfs(lst, r, c):
nr = len(lst)
nc = len(lst[0])
lst[r][c] = 0
if r-1 >= 0 and lst[r-1][c]==1:
dfs(lst, r-1,c)
if r+1 < nr and lst[r+1][c]==1:
dfs(lst, r+1,c)
if c-1 >= 0 and lst[r][c-1]==1:
dfs(lst, r,c-1)
if c+1 < nc and lst[r][c+1]==1:
dfs(lst, r,c+1)
lst = [[1,1,1,1,0],[1,1,1,1,0],[1,1,0,0,0],[0,0,1,0,1,]]
nr = len(lst)
nc = len(lst[0])
num_islands = 0
for r in range(nr):
for c in range(nc):
if lst[r][c] == 1:
num_islands +=1
dfs(lst, r, c)
print(num_islands)
# 算法二 广度优先搜索
lst = [[1,1,1,1,0],[1,1,1,1,0],[1,1,0,0,0],[0,0,1,0,1,]]
nr = len(lst)
nc = len(lst[0])
num_islands = 0
for r in range(nr):
for c in range(nc):
if lst[r][c] == 1:
num_islands +=1
lst[r][c] = 0
from collections import deque
from django.db.migrations import graph
2
def search(name):#广度优先搜索(BFS)
# deque()函数创建一个双端队列(先进先出)
# 注意deque是python标准库cillections中的一个模块
search_quene = deque()
search_quene += graph[name]
# 创建空列表的目的:为了防止后边添加到队列里的元素与之前的重复出现
# 所以我加入一个空列表,将判断完成的数据添加的这个列表,将准备进入列表的数据与这个列表元素对比,确保没有重复元素再次进入队列,防止无限循环产生
searched = []
while search_quene:
# 队列中,pop()默认抛出右边元素,但是我们希望,append()从右边入队,popleft()从左边出队
person = search_quene.popleft()
if person not in searched:
#person_is_not()是一个判断函数,我们需要判断我们查找的内容是否满足我们的需求
if person_is_not(person):
print (person+" is this")
return True
else:
search_quene += graph[person]
searched.append(person)
return False
def myDijkstra(statr:int , lst:list):
"""
:param statr: 开始的地点
:param lst: 各个城市之间的距离, 二维数组,就是用行列坐标表示图形上两点之间的距离。
:return: 到各个城市的最短距离
"""
# city 未被当作中间节点的城市列表
city = [x for x in range(len(lst)) if x != statr]
# 城市顺序
cityorder = [statr]
citylength = lst[statr] # len1 是一一维列表,里面包含着 成市 n 到各个城市的初始距离
# 用循环判断,城市n 到其他城市中最短的距离
while len(city):
idenx1 =city[0]
for i in city:
if citylength[i] < citylength[idenx1]:
idenx1 = i
# 将做过中间节点的移出city
city.remove(idenx1)
# 添加到城市最近列表
cityorder.append(idenx1)
# 更新成市 n 到各个城市之间的最短距离
for i in city:
# 当新的路线距离更进时,会更新 个城市直接的距离
if citylength[idenx1]+lst[idenx1][i] < citylength[i]:
citylength[i] = citylength[idenx1]+lst[idenx1][i]
return citylength
if __name__ == '__main__':
max = 999999 # max即表示为无法直达
graph = [
[5, max, 10, max, 30, 100],
[max, max, 5, max, max, max],
[max, 15, max, 50, max, max],
[max, max, max, max, max, 10],
[max, max, max, 20, max, 60],
[max, 15, max, max, max, max],
]
inf = 999999
mgraph = [[0, 1, 12, inf, inf, inf],
[inf, 0, 9, 3, inf, inf],
[inf, inf, 0, inf, 5, inf],
[inf, inf, 4, 0, 13, 15],
[inf, inf, inf, inf, 0, 4],
[inf, inf, inf, inf, inf, 0]]
len1 = myDijkstra(0,graph)
print(len1)
len2 = myDijkstra(0, mgraph)
print(len2)
def startwith(start: int, mgraph: list) -> list:
passed = [start]
# 初始化数组,一共有多少个城市 并为城市编号
nopass = [x for x in range(len(mgraph)) if x != start]
print('nopass',nopass)
# 到直接各个点之间的最短距离,不能直接到达的距离就是 10086
dis = mgraph[start]
print(dis)
# 执行循环,找出初始位置到各个点的最短路径
while len(nopass):
idx = nopass[0]
for i in nopass:
if dis[i] < dis[idx]:
idx = i
nopass.remove(idx)
# 还有那个的点未被访问
print("111111",nopass)
passed.append(idx)
# 最短路径的走法
print("22222",passed)
for i in nopass:
if dis[idx] + mgraph[idx][i] < dis[i]:
dis[i] = dis[idx] + mgraph[idx][i]
return dis
def dijkstra(graph, start_Node, path, cost, max):
"""
graph:二维数组,就是用行列坐标表示图形上两点之间的距离。
start_Node:起始点
path[i] 表示vi节点的前一个节点,即中转点。
cost[i] 表示V0到Vi的已知最短路径长度
mid_Node:中转点,以已求得V0到Vi的最短路径的Vi作为中转点。
NEXT_Node:尝试优化的点,以中转点为中心,检测NEXT_Node直达V0方案,和经过mid_Node中转到V0的方案哪个更优
check_Node:索引,搜索cost数组里最短路径的点,最短的点会赋值给mid_Node,作为中转点。
"""
lenth = len(graph)
v = [0] * lenth # V数组初始化为0,用于标记该点是否已取得最短路径
# 初始化 path,cost,V
for i in range(lenth):
if i == start_Node:
v[start_Node] = 1
else:
cost[i] = graph[start_Node][i] # cost获取起点至其他点的直达权重
path[i] = (start_Node if (cost[i] < max) else -1) # 前置点为起点或-1(无法直达起点)
# print v, cost, path
for i in range(1, lenth): # 遍历的数等于除去起点的点的数量
minCost = max # 初始值取最大
mid_Node = -1
for check_Node in range(lenth): # 搜索一个到起点V0最近的点,作为中转点mid_Node
if v[check_Node] == 0 and cost[check_Node] < minCost: # mid_Node点未取得最短路径,且路径权重小于最小值,则获取w,也就是先取得
minCost = cost[check_Node]
mid_Node = check_Node
if mid_Node == -1: break # 找不到权重小于max的点
# 剩下都是不可通行的节点,跳出循环
v[mid_Node] = 1 # check_Node已取得最短路径
for NEXT_Node in range(lenth):
if v[NEXT_Node] == 0 and (graph[mid_Node][NEXT_Node] + cost[mid_Node] < cost[
NEXT_Node]): # 检查所有未遍历的点NEXT_Node,检测前面获取的mid_Node对NEXT_Node的影响
cost[NEXT_Node] = graph[mid_Node][NEXT_Node] + cost[mid_Node] # 更新权值
path[NEXT_Node] = mid_Node # 更新路径
# for 更新其他节点的权值(距离)和路径
return path