一、110. 字符串接龙
题目连接:110. 字符串接龙 (kamacoder.com)
Leetcode链接:127. 单词接龙 - 力扣(LeetCode)
文章讲解:代码随想录 (programmercarl.com)——110. 字符串接龙
思路:求最短路径——bfs。先判断点与点之间是否可以相连,如果两个点只差一个字符,那么可以相连,连接后找出最短路径,广搜找到的终点一定就是最短路径。
Note:无向图,需要记录字符串是否走过。
"""
BFS
"""
from collections import deque
def bfs(beginStr, endStr, strList):
# 将字符串转换为集合方便查找
strSet = set(strList)
# 记录字符串是否被访问过及路径长度
visiteMap = {beginStr: 1}
# 初始化队列
que = deque()
que.append(beginStr)
# 如果队列不为空
while que:
# 取出队列口元素
word = que.popleft()
# 获取当前字符串路径长度
path = visiteMap[word]
# 对字符串中每个字母进行替换
for i in range(len(word)):
# 遍历26个字母
for j in range(26):
# ord获取字母的ASIC码,chr将ASIC码返回字母字符
newWord = word[:i] + chr(j + ord('a')) + word[i + 1:]
# 检查 newWord 是否为结束字符串,返回路径长度+1
if newWord == endStr:
return path + 1
# 如果 newWord 在集合中且未被访问
if newWord in strSet and newWord not in visiteMap:
# 记录新字符串的路径长度,并添加到队列
visiteMap[newWord] = path + 1
que.append(newWord)
# 未找到
return 0
if __name__ == '__main__':
n = int(input())
beginStr, endStr = input().split()
strList = [input().strip() for _ in range(n)]
result = bfs(beginStr, endStr, strList)
print(result)
二、105. 有向图的完全可达性
题目连接:105. 有向图的完全可达性 (kamacoder.com)
文章讲解:代码随想录 (programmercarl.com)——105. 有向图的完全可达性
思路:本题为有向图搜索全路径问题。
"""
DFS
写法一:终止条件部分,dfs 处理当前访问节点
"""
# 1. 确定递归函数,参数
# grid: 地图
# key: 当前需要处理的节点
# visited: 记录走过哪些房间
def dfs(grid, key, visited):
# 2. 确定终止条件
# case1. 处理当前节点,如果当前节点为True,即访问过,终止递归
if visited[key]:
return
# 标记当前节点已访问
visited[key] = True
# 遍历邻接节点
for keys in grid[key]:
# dfs递归
dfs(grid, keys, visited)
if __name__ == '__main__':
n, m = map(int, input().split())
# 创建邻接表,长度为 n + 1 ,且每个元素都初始成空列表。
# 用 n + 1 是因为需要用到索引从 1 到 n。
grid = [[] for _ in range(n + 1)]
# 循环m次
for _ in range(m):
# 读取每一行的输入,将该行字符串分割成多个部分,int转换为整数
s, t = map(int, input().split())
# 在邻接表中,将节点 's' 的邻接表中添加节点 't'
grid[s].append(t)
# 创建一个长度为 n + 1 的 False 列表
visited = [False] * (n + 1)
# 从节点1开始深搜
dfs(grid, 1, visited)
# 检查是否所有节点都被访问过,因为从1开始,不需要访问第一个节点
for i in range(1, n + 1):
# 如果有没访问的,说明不可以到达任何节点,返回-1
if not visited[i]:
print(-1)
break
else:
print(1)
"""
DFS
写法二:dfs 处理下一个节点,注释的地方是和写法一不同的
"""
def dfs(grid, key, visited):
# 直接进入循环
for keys in grid[key]:
# 确认下一个节点没访问过
if not visited[keys]:
visited[keys] = True
dfs(grid, keys, visited)
if __name__ == '__main__':
n, m = map(int, input().split())
grid = [[] for _ in range(n + 1)]
for _ in range(m):
s, t = map(int, input().split())
grid[s].append(t)
visited = [False] * (n + 1)
# 节点1预处理,设置成访问过
visited[1] = True
dfs(grid, 1, visited)
for i in range(1, n + 1):
if not visited[i]:
print(-1)
break
else:
print(1)
"""
BFS
"""
from collections import deque
def bfs(grid, key, visited):
que = deque()
que.append(key)
while que:
key = que.popleft()
for keys in grid[key]:
if not visited[keys]:
que.append(keys)
visited[keys] = True
if __name__ == '__main__':
n, m = map(int, input().split())
grid = [[] for _ in range(n + 1)]
for _ in range(m):
s, t = map(int, input().split())
grid[s].append(t)
visited = [False] * (n + 1)
visited[1] = True
bfs(grid, 1, visited)
for i in range(1, n + 1):
if not visited[i]:
print(-1)
break
else:
print(1)
三、106.岛屿的周长
题目连接:106. 岛屿的周长 (kamacoder.com)
文章讲解:代码随想录 (programmercarl.com)——106.岛屿的周长
思路1:遍历每一个空格,遇到岛屿则计算其上下左右空格情况,如果有水域则是一条边,如果出界了也是一条边。
"""
思路1:遍历每一个空格,遇到岛屿则计算其上下左右空格情况,
如果有水域则是一条边,如果出界了也是一条边。
"""
def boundary(grid):
# 行
n = len(grid)
# 列
m = len(grid[0])
dir = [(0, 1), (1, 0), (0, -1), (-1, 0)]
result = 0
for i in range(n):
for j in range(m):
# 如果是陆地,则遍历四个方向
if grid[i][j] == 1:
for k in dir:
# 计算周围坐标
x = i + k[0]
y = j + k[1]
# 如果在边界上,或者有水
if x < 0 or x >= n or y < 0 or y >= m or grid[x][y] == 0:
result += 1
return result
if __name__ == '__main__':
n, m = map(int, input().split())
grid = [list(map(int, input().split())) for _ in range(n)]
result = boundary(grid)
print(result)
思路2:计算出所有岛屿数量 * 4,得到所有岛屿边长,但是每两个岛屿相连,边长需要相应减2。需要统计所有岛屿数量 sum,相邻岛屿数量 cover,result = sum * 4 - cover * 2
"""
思路2:计算出所有岛屿数量 * 4,得到所有岛屿边长,但是每两个岛屿相连,边长需要相应减2。
需要统计所有岛屿数量 sum,相邻岛屿数量 cover,result = sum * 4 - cover * 2
"""
def boundary(grid):
# 行
n = len(grid)
# 列
m = len(grid[0])
dir = [(0, 1), (1, 0), (0, -1), (-1, 0)]
# 统计所有岛屿数量
sum = 0
# 统计相连岛屿数量
cover = 0
for i in range(n):
for j in range(m):
# 如果是陆地,统计岛屿数量
if grid[i][j] == 1:
sum += 1
# 为避免重复运算,只需要统计上和左即可。
# 统计上边是否为陆地
if i - 1 >= 0 and grid[i - 1][j] == 1:
cover += 1
# 统计左边是否为陆地
if j - 1 >= 0 and grid[i][j - 1] == 1:
cover += 1
result = sum * 4 - cover * 2
return result
if __name__ == '__main__':
n, m = map(int, input().split())
grid = [list(map(int, input().split())) for _ in range(n)]
result = boundary(grid)
print(result)