https://leetcode.cn/problems/reconstruct-itinerary/description/

本质还是模板题,难点在于如何管理机票

<aside> 💡

输入前的预处理:


回溯三部曲:

map<string, vector<bool>> used;
int totalItinerary;
vector<string> cur;
vector<string> ans;

void backtracking(const string& from, map<string, vector<string>>& mp) {
    if (!ans.empty()) {
        return;
    }
    if (cur.size() == totalItinerary) {
        ans = cur;
        return;
    }

    const vector<string>& toList = mp[from];
    vector<bool>& usedFrom = used[from];
    for (int i = 0; i < toList.size(); ++i) {
        // 跳过已经使用过的机票
        if (i < toList.size() && usedFrom[i]) {
            continue;
        }
        // 回溯
        usedFrom[i] = true;
        cur.push_back(toList[i]);
        backtracking(toList[i], mp);
        cur.pop_back();
        usedFrom[i] = false;

        // 树层去重
        while (i + 1 < toList.size() && toList[i + 1] == toList[i]) {
            ++i;
        }
    }
}

vector<string> findItinerary(vector<vector<string>>& tickets) {
    // 行程的长度
    totalItinerary = tickets.size() + 1;
    // 使用map管理机票,<from, toList>
    map<string, vector<string>> mp;
    for (auto& v : tickets) {
        mp[v[0]].push_back(v[1]);
    }
    for (auto& item : mp) {
        // 排序+构建used数组
        std::sort(item.second.begin(), item.second.end());
        used[item.first] = vector<bool>(item.second.size(), false);
    }

    cur.push_back("JFK");
    backtracking("JFK", mp);

    return ans;
}