好久没写题解了,今天做了一道图题,觉得解法很不错。
题目:
Given a list of airline tickets represented by pairs of departure and arrival airports [from, to]
, reconstruct the itinerary in order. All of the tickets belong to a man who departs from JFK
. Thus, the itinerary must begin with JFK
.
重建行程,边会重复,要求是将所有行程都串起来,多种结果,返回字母序小的;
分析:本来我的想法是用BFS,但是不好处理字母序列,每次都取左小的一个,但是可能会导致有的边没有被遍历到;
解答是用DFS,一只向前走,如果走完终点了则将该点加入结果,最后结果逆序下;
比较巧妙的是非递归的解法,借助栈实现的:
/** 非递归---迭代的方法,使用栈 */ class Solution { public List<String> findItinerary(String[][] tickets) { Map<String, List<String>> map = new HashMap<>(); for (String[] ticket : tickets) { String start = ticket[0]; String end = ticket[1]; if (!map.containsKey(start)) { map.put(start, new ArrayList<>()); } map.get(start).add(end); } for (String node : map.keySet()) { Collections.sort(map.get(node)); } List<String> res = new ArrayList<>(); Stack<String> stack = new Stack<>(); stack.push("JFK"); while (!stack.isEmpty()) { String cur = stack.peek(); if (map.containsKey(cur) && map.get(cur).size() > 0) { //还能前进 String next = map.get(cur).get(0); map.get(cur).remove(0); stack.push(next); } else { //不能前进了,则出栈,加入结果 res.add(cur); stack.pop(); } } Collections.reverse(res); return res; } }
DFS的代码:
class Solution { public List<String> findItinerary(String[][] tickets) { Map<String, List<String>> map = new HashMap<>(); for (String[] ticket : tickets) { String start = ticket[0]; String end = ticket[1]; if (!map.containsKey(start)) { map.put(start, new ArrayList<>()); } map.get(start).add(end); } for (String node : map.keySet()) { Collections.sort(map.get(node)); } List<String> res = new ArrayList<>(); String cur = "JFK"; dfs(map, cur, res); Collections.reverse(res); return res; } private void dfs(Map<String, List<String>> map, String node, List<String> res) { //如果能继续向下递归,则继续 while (map.containsKey(node) && !map.get(node).isEmpty()) { String next = map.get(node).get(0); map.get(node).remove(0); dfs(map, next, res); } //否则将该点加入结果 res.add(node); } }