332.重新安排行程

89 阅读2分钟

题目:
给你一份航线列表 tickets ,其中 tickets[i] = [fromi, toi] 表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。

所有这些机票都属于一个从 JFK(肯尼迪国际机场)出发的先生,所以该行程必须从 JFK 开始。如果存在多种有效的行程,请你按字典排序返回最小的行程组合。

  • 例如,行程 ["JFK", "LGA"] 与 ["JFK", "LGB"] 相比就更小,排序更靠前。

假定所有机票至少存在一种合理的行程。且所有的机票 必须都用一次 且 只能用一次。
解法: Hierholzer 算法用于在连通图中寻找欧拉路径,其流程如下:

  1. 从起点出发,进行深度优先搜索。
  2. 每次沿着某条边从某个顶点移动到另外一个顶点的时候,都需要删除这条边。
  3. 如果没有可移动的路径,则将所在节点加入到栈中,并返回。

作者:LeetCode-Solution 链接:leetcode.cn/problems/re… 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

tickets=[["JFK","KUL"],["JFK","NRT"],["NRT","JFK"]]这种路径,无论是先走 tickets[1]还是tickets[2] ,"KUL"都会最先进入ans

import "sort"
func findItinerary(tickets [][]string) []string {
	itinerary := make(map[string]*Destinations)
	ans := make([]string, 0)
	for i := range tickets {
		if dests, ok := itinerary[tickets[i][0]]; ok {
			dests.Insert(tickets[i][1])
		} else {
			d := &Destinations{
				destinations: make([]string, 0),
			}
			d.Insert(tickets[i][1])
			itinerary[tickets[i][0]] = d
		}
	}
    
    // dfs函数内部用到了dfs,需要先定义dfs
    var dfs func(curr string)
    dfs = func (city string){
		for len(itinerary) != 0 {
			ds, ok := itinerary[city]
			if  !ok || ds.Len() == 0 {
				break
			}
			next := ds.Pop()
			if ds.Len() == 0 {
				delete(itinerary, city)
			}
			dfs(next)
		}
		ans = append(ans, city)
	}
	dfs("JFK")
	for left, right := 0, len(ans) - 1; left < right; left, right = left + 1, right - 1 {
		ans[left], ans[right] = ans[right], ans[left]
	}
	return ans
}

type Destinations struct {
    destinations []string
}

func (d *Destinations) Less(i, j int) bool{
	return d.destinations[i] < d.destinations[j]
}
func (d *Destinations) Swap(i, j int) {
	d.destinations[i], d.destinations[j] = d.destinations[j], d.destinations[i]
}
func (d *Destinations) Len() int{
	return len(d.destinations)
}
func (d *Destinations) Insert(dest string) {
	d.destinations = append(d.destinations, dest)
	sort.Sort(d)
}
// 最小的先出
func (d *Destinations) Pop() string {
	x := d.destinations[0]
	d.destinations = d.destinations[1:]
	return x
}