先学习一下欧拉回路是怎么一回事。
对于图中这七个节点,从节点1出发,最终要到达节点1,并且每条路只能走一次,且每条路都得走过一次。
使用dfs,如果算法按照字典序的排列方式选择下一个节点。
第一部分:那么算法的流程是,节点1--> 节点2-->节点3-->节点1。这时候到达节点1后发现,节点1无路可走了兄弟们,退回到节点3继续走呗。
第二部分:接着流程是,节点3--> 节点4-->节点5-->节点3。退退退,退到节点5发现也无路可走,再退到节点4继续。
第三部分:接着流程是,节点4--> 节点6-->节点7-->节点4。最终所有的路都走了一遍。
我们发现,第二部分的流程,从3开始,最终到达3,那么可以插入到第一部分的节点3上。
第一部分的流程变成:节点1--> 节点2-->节点3--> 节点4-->节点5-->节点3-->节点1。
第三部分流程,从4开始,最终到达4,那么可以插入到第一部分的节点4上。
第一部分的流程变成:节点1--> 节点2-->节点3--> 节点4--> 节点6-->节点7-->节点4-->节点5-->节点3-->节点1。
这一套流程下来,所有的边都走过一遍,且只走一遍。
再重新分析一遍第一部分,节点1--> 节点2-->节点3-->节点1,发现最终到达节点1的时候,无路可走,节点3又可以走其他路,那么可以推出,从节点3-->节点1这一段路应该是最后的一段路。可以先加入列表ans中。
第二部分流程是,节点3--> 节点4-->节点5-->节点3。发现最终到达节点3的时候,无路可走,节点4又可以走其他路,那么可以推出,从节点4-->节点5-->节点3。这一段路应该是倒数第二段路。可以加入列表ans中。
第三部分流程是,节点4--> 节点6-->节点7-->节点4。最终所有的路都走了一遍。这是从节点4到达节点4的一段路,是正着走的一段路,ans中倒着走的一段路。
看例题:
这是有向图,并且路径可能重复。例如可能存在两条一样的路:JFK-->SFO。
class Solution:
def findItinerary(self, tickets: List[List[str]]) -> List[str]:
edge = defaultdict(list)
ans = []
for x, y in tickets:
edge[x].append(y)
def dfs(u):
qu = edge[u]
qu.sort()
while qu:
v = qu.pop(0)
dfs(v)
ans.append(u)
dfs('JFK')
return ans[::-1]