返回轨道
算法 · 2026-05-14 · 24 阅读

P183 行程安排

算法 24 阅读

信号摘要

难度:Medium · 时长:20:58 · leetcode 332 · lintcode 1288

P183 行程安排

未对外公开播放权限
点击查看说明

描述

这个题目说的是,给你一组由出发机场与到达机场 [from, to] 表示的机票,你要按顺序把途经的机场排列出来。每个机场都由 3 个大写字母表示,并且一开始从 JFK 机场出发。

注意,所有的机票都要用上,并且它们至少可以组成一个有效的行程。如果存在多个有效行程,则返回字典序最小的那个行程。

为了方便演示,我们假设用单个大写字母来表示机场,并且一开始由 A 机场出发。

比如说,给你的机票是:

[B, D] [A, B] [C, E] [D, C]

这 4 张机票只能构成一个有效行程:

[A, B, D, C, E]

再比如说,给你的机票是:

[A, C] [A, B] [C, B] [B, A]

这 4 张机票可以组成两个有效的行程:

[A, B, A, C, B] [A, C, B, A, B]

在这两个有效行程中,出发机场都是 A,然后第一个行程来到机场 B,而第二个行程来到机场 C。B 在字典序上是小于 C 的,因此我们要返回第一个有效行程:

[A, B, A, C, B]

代码

public class AlgoCasts {

  class Pair<F, S> {
    public F first;
    public S second;
    Pair(F first, S second) {
      this.first = first;
      this.second = second;
    }
  }

  private boolean dfs(String from, int total, List<String> result,
                      Map<String, List<Pair<String, Boolean>>> map) {
    if (result.size() == total) return true;
    List<Pair<String, Boolean>> tos = map.get(from);
    if (tos == null) return false;

    for (Pair<String, Boolean> e: tos) {
      if (e.second) continue;
      e.second = true;
      result.add(e.first);
      if (dfs(e.first, total, result, map)) return true;
      result.remove(result.size()-1);
      e.second = false;
    }
    return false;
  }

  // Time: O(n!), Space: O(n)
  public List<String> findItineraryBruteForce(List<List<String>> tickets) {
    Map<String, List<Pair<String, Boolean>>> map = new HashMap<>();
    for (List<String> e: tickets) {
      if (!map.containsKey(e.get(0))) map.put(e.get(0), new ArrayList<>());
      map.get(e.get(0)).add(new Pair<>(e.get(1), false));
    }
    for (List<Pair<String, Boolean>> list: map.values())
      list.sort(Comparator.comparing(pair -> pair.first));
    int total = tickets.size() + 1;
    List<String> result = new ArrayList<>();
    result.add("JFK");
    dfs("JFK", total, result, map);
    return result;
  }

  private void hierholzer(String from, List<String> result,
                          Map<String, PriorityQueue<String>> map) {
    PriorityQueue<String> tos = map.get(from);
    while (tos != null && !tos.isEmpty())
      hierholzer(tos.poll(), result, map);
    result.add(0, from);
  }

  // Time: O(n*log(n)), Space: O(n)
  public List<String> findItineraryHierholzer(List<List<String>> tickets) {
    Map<String, PriorityQueue<String>> map = new HashMap<>();
    for (List<String> e: tickets) {
      if (!map.containsKey(e.get(0))) map.put(e.get(0), new PriorityQueue<>());
      map.get(e.get(0)).add(e.get(1));
    }
    List<String> result = new LinkedList<>();
    hierholzer("JFK", result, map);
    return result;
  }

}

📡 通讯频道