leetcode322(hard)—图论+回溯算法—重新安排行程

欧拉路径

这题其实是经典构造的欧拉路径,题目已经明确说了,满足欧拉图的条件,因此我们用经典的hierholzer算法构造就好了

还需要满足升序条件,那提前进行排序就行

1、逆序排序,因为我们用pop,所以将最小的排在最后

2、pop相当于删除一条有向边,保证了不重复走边

3、构造欧拉路径的方式是回溯到当前层函数时,将当前层的from加入进路径,所以路径其实是反的

4、最后记得逆序路径

class Solution:
    from collections import defaultdict
    def findItinerary(self, tickets: List[List[str]]) -> List[str]:
        my_dict = defaultdict(list)
        for ticket in tickets:
            my_dict[ticket[0]].append(ticket[1])
        for key in my_dict:
            my_dict[key].sort(reverse=True)
        
        res = []
        def dfs(from_airport):
            while my_dict[from_airport]:
                next_airport = my_dict[from_airport].pop()
                dfs(next_airport)
            res.append(from_airport)
        dfs("JFK")
        return res[::-1]

其实我一开始的想法是用回溯寻找一条满足条件的路径

但是这个超时了,for循环代价太大

class Solution:
    def findItinerary(self, tickets: List[List[str]]) -> List[str]:
        tickets.sort()
        path = []
        path.append("JFK")
        used = [False] * len(tickets)
        def backtracking(from_air_port):
            if len(path) == len(tickets) + 1:   
                return True
            for i, ticket in enumerate(tickets):
                if used[i] == True or ticket[0] != from_air_port:
                    continue
                used[i] = True
                path.append(ticket[1])
                if backtracking(ticket[1]):
                    return True
                used[i] = False
                path.pop()
        if backtracking("JFK"):
            return path
        return []

        
            

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值