刷题第二十五天 332. 重新安排行程

332.重新安排行程

class Solution:
    def findItinerary(self, tickets: List[List[str]]) -> List[str]:

        def back_tracking(result, tickets, subset, used):
            if len(subset) == len(tickets) and subset[0][0] == 'JFK':
                result.append(subset.copy())
                return
            for i in range(0, len(tickets)):
                if used[i] == 1:
                    continue
                if subset and tickets[i][0] != subset[-1][1]:
                    continue
                subset.append(tickets[i])
                used[i] = 1
                back_tracking(result, tickets, subset, used)
                subset.pop()
                used[i] = 0
        subset = []
        used = [0] * len(tickets)
        result = [] #以JFK开头的所有路径
        result3 = [] #记录字典排序最小的结果
        back_tracking(result, tickets, subset, used)
        print(result)
        for i in range(0, len(result)):                 #第一层遍历结果中的不同路径
            result2 = []                                #将二维list转化为一维list
            for j in range(0, len(result[i])):         
                if j == 0:
                    result2.append(result[i][j][0])     #如果是二维list中的第一个元素,那么头两个元素都加入
                    result2.append(result[i][j][1])     
                else:
                    result2.append(result[i][j][1])     #其他情况只加入第二个元素, result2得到了所有以JFK开头的一维list路径
            if i == 0 :
                result3 = result2                       #记录字典排序最小的字符串
            elif ''.join(result2) < ''.join(result3):   #如果当前结果的字典排序小于之前记录的,那么记录当前结果
                result3 = result2
        
        return result3

自己写了一版,但是没有A,超时了。具体思路是和全排列类似,找出所有头尾相连的以JFK出发的路径 然后用字符串比较字典排序大小,返回最小的。

class Solution:
    def findItinerary(self, tickets: List[List[str]]) -> List[str]:
        tickets.sort() # 先排序,这样一旦找到第一个可行路径,一定是字母排序最小的
        used = [0] * len(tickets)
        path = ['JFK']
        results = []
        self.backtracking(tickets, used, path, 'JFK', results)
        return results[0]
    
    def backtracking(self, tickets, used, path, cur, results):
        if len(path) == len(tickets) + 1:  # 终止条件:路径长度等于机票数量+1
            results.append(path[:])  # 将当前路径添加到结果列表
            return True
        
        for i, ticket in enumerate(tickets):  # 遍历机票列表
            if ticket[0] == cur and used[i] == 0:  # 找到起始机场为cur且未使用过的机票
                used[i] = 1  # 标记该机票为已使用
                path.append(ticket[1])  # 将到达机场添加到路径中
                state = self.backtracking(tickets, used, path, ticket[1], results)  # 递归搜索
                path.pop()  # 回溯,移除最后添加的到达机场
                used[i] = 0  # 标记该机票为未使用
                if state:
                    return True  # 只要找到一个可行路径就返回,不继续搜索

看了解析之后,有几个点改进的地方:

1. 回溯收集路径的时候加入一个cur参数,来记录当前到哪了,这样的话可以直接构建一维的list,初始的时候cur一定是JFK,后面每次递归cur就是tickt[1]

2. 可以先对tickets进行sort,这样先找到的路径就一定是最短的

3. 回溯函数加一个返回值,如果返回真,说明找到了,直接return,到主函数返回结果就行。

51. N皇后

pass

37. 解数独

pass

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值