110. 字符串接龙
110. 字符串接龙
思路:
找最短路径适合用广搜,广搜的探索范围比较广,能更快地找到最短路径。采用深搜的话,还需判断所获取的路径是否为最短。
- 1. 由于 abc -> dbc -> dec -> def 的最短路径为4,因此最短路径的数目其实就是这条路径上的节点数目。
- 2. 关键:如何构造出相邻节点只有一个字符不同的图?通过构造judge()函数来判断两个字符串是否只有一位不同,如果是的话,则这两个节点可以相连。(题目放宽了限制,字符串都是等长的,因此judge()函数可以覆盖到所有情况)
- 3. 关键:如何找到最短路径?由于是广搜,因此第一个找到end_str的就是最短路径,故在遍历的过程中,可以通过一个字典来存储信息,key存储当前所在字符串,value表示begin_str到当前字符串cur_str的路径长度,随着广搜的进行,路径长度也随着+1,直到cur_str和end_str只有一个字符串相差时,此时路径长度+1后就可以print()进行输出。
- 初始化,如果end_str和begin_str,本身到本身,路径长度为0。否则begin_str要到end_str至少需要经历一个节点(begin_str), 因此begin_str的初始化为 [begin_str, 1]。
BFS广度搜索解法
## 过程: begin_str + strList(1) + strList(2) + .. + end_str
## 但关键在于,每个相邻的字符串有一个字符的不同。
## 解法关键:1. 如何构造出相邻节点只有一个字符不同的图 2. 如何找到最短路径
from collections import dequedef judge(s1, s2): ## 判断两个字符串是否只有一个字符串相同"""input: s1:str, s2:stroutput: bool"""str_len = len(s1)count = 0 ### 计数两个等长字符串有多少个字符不同for i in range(str_len):if s1[i] != s2[i]:count += 1if count == 1: ### s1 和 s2 只有一位字符不同return Trueelse:return Falsedef main():num = int(input())begin_str, end_str = input().split()if begin_str == end_str:print(0)return strList = []for _ in range(num):cur_str = input()strList.append(cur_str)visited = [False] * num## bfs, 定义一个队列,队列存储的是一个字典 key: cur_str, value : path_lenth (表示从begin_str到当前cur_str的最短路径)queue = deque([])queue.append([begin_str, 1]) ## begin_str 到 begin_str 的最短路径为 1 while queue:cur_str, cur_step = queue.popleft()if judge(cur_str, end_str): ## 最后能到end_str时cur_step += 1print(cur_step)return for i in range(num):if visited[i] == False and judge(cur_str, strList[i]):next_str = strList[i]visited[i] = True# cur_step += 1queue.append([next_str, cur_step+1])print(0)if __name__ == "__main__":main()
注意:
for i in range(num):if visited[i] == False and judge(cur_str, strList[i]):next_str = strList[i]visited[i] = True# cur_step += 1queue.append([next_str, cur_step+1])
不能先赋值再将这个值append到数组中,因为循环还在继续,如果这样做的话会导致cur_step不断累积啊,本来只是间隔为1,可能被累积影响变成间隔为 8 ..