# -*- coding: utf-8 -*-
'''
Python程序员面试算法宝典---解题总结: 第二章 栈、队列与哈希 2.9 如何从给定的车票中找出旅程
题目:
给定一趟旅途旅程中所有的车票信息,根据这个车票信息找出这趟旅程的路线。例如:
给定下面的车票: 西安到成都,北京到上海,大连到西安,上海到大连。
那么可以得到旅程的路线为: 北京->上海,上海->大连,大连->西安,西安->成都。
假定给定的车票不会有环,也就是说有一个城市之作为终点而不会作为起点。
分析:
这个看上去就是给定若干个节点到节点的指向关系,求出整个链表。
由于队列实际就是一种特殊的链表。
考虑到双端队列,我们可以不断根据给定的节点指向关系,来放置不同的节点。
例如西安到成都,放置后的结果为:
西安,成都
北京到上海,无法确认北京应该放置在西安前面还是后面。
或者可以这样,建立字典:
<西安,成都>
<北京,上海>
<大连,西安>
<上海,大连>
先根据第一个键值对<西安,成都>中的末尾元素成都,以成都继续在字典中寻找,寻找不到,
则说明成都是末尾站,寻找到,则继续找下面的站,这样就找到了整个站的先后关系,存入到
双端队列中。
关键:
1 我的方法是可行的
书上解法:
同时设置input和reverseInput,遍历input中的每个key,如果某个key不在reverseInput中,
则该key就是起点。
参考:
Python程序员面试算法宝典
'''
from collections import deque
class Route(object):
def __init__(self):
self.queue = deque()
self.dict = dict()
self.reverseDict = dict()
def addTicket(self, key, value):
self.dict[key] = value
self.reverseDict[value] = key
def findRoute(self, beginKey, beginValue):
if beginKey is None or beginValue is None:
return
self.queue.append(beginKey)
self.queue.append(beginValue)
beginKeyCopy = beginKey
beginValueCopy = beginValue
# 向后寻找每个节点的后继节点
while beginValue in self.dict:
beginKey = self.dict[beginValue]
self.queue.append(beginKey)
beginValue = beginKey
# 向前寻找每个节点的前向节点
while beginKeyCopy in self.reverseDict:
beginValue = self.reverseDict[beginKeyCopy]
self.queue.appendleft(beginValue)
beginKeyCopy = beginValue
def printRoute(self):
info = ''
for value in self.queue:
if info:
info += '->' + str(value)
else:
info += str(value)
print info
class OptimizedRoute(object):
def __init__(self):
self.queue = deque()
self.dict = dict()
self.reverseDict = dict()
def addTicket(self, key, value):
self.dict[key] = value
self.reverseDict[value] = key
def findRoute(self):
# 寻找起点
start = None
for key, value in self.dict.iteritems():
if key not in self.reverseDict:
start = key
break
if start is None:
print "start is None, it it not correct"
return
result = start
while start in self.dict:
start = self.dict[start]
result += '->' + start
return result
def process():
route = OptimizedRoute()
route.addTicket('西安', '成都')
route.addTicket('北京', '上海')
route.addTicket('大连', '西安')
route.addTicket('上海', '大连')
result = route.findRoute()
print result
if __name__ == "__main__":
process()