トピック:
チケットの2次元文字列配列[from、to]が与えられると、サブ配列の2つのメンバーはそれぞれ、飛行機が出発して着陸する空港の場所を表し、旅程は再計画され、並べ替えられます。これらのチケットはすべて、JFK(JFK国際空港)を出発する紳士のものであるため、旅程はJFKから開始する必要があります。
促す:
- 有効な旅程が複数ある場合は、文字の自然な順序で最小の旅程の組み合わせを返してください。たとえば、旅程["JFK"、 "LGA"]は["JFK"、 "LGB"]よりも小さく、順序は高くなります
- すべての空港は3つの大文字(空港コード)で表されます。
- すべてのチケットに少なくとも1つの妥当な旅程があると想定します。
- すべてのチケットは一度だけ使用する必要があります。
例1:
到入:[["MUC"、 "LHR"]、["JFK"、 "MUC"]、["SFO"、 "SJC"]、["LHR"、 "SFO"]]
後出:["JFK"、 「MUC」、「LHR」、「SFO」、「SJC」]
示例2:
入力:[["JFK"、 "SFO"]、["JFK"、 "ATL"]、["SFO"、 "ATL"]、["ATL"、 "JFK"]、["ATL"、 "SFO "]]
出力:[" JFK "、" ATL "、" JFK "、" SFO "、" ATL "、" SFO "]
説明:別の有効なストロークは[" JFK "、" SFO "、" ATL "、" JFK "、" ATL "、" SFO "]。しかし、それは当然、より大きく、より低くランク付けされます。
ソース:
問題解決のアイデア:バックトラック
各チケットの使用状況を記録するために使用される配列変数を定義します。デフォルトでは使用されません(false)。通過した空港を記録するための配列パスを定義します。
旅程の最小の組み合わせを見つけるために、すべてのチケットを並べ替えて、組み合わせの1つが見つかったときに戻る必要があります。
JFKから始めたいので、最初にJFKをパスに書き込みます。
- 再帰的終了条件:パス内の空港の数は、チケットの数+ 1に等しくなります(すべてのチケットが1回使用されるため)
- 再帰+バックトラッキング:すべてのチケットをトラバースし、条件を満たすすべてのチケットを試します(ここでは、コードを単純化するためにトラバーサルが使用されていますが、これは非効率的であり、空港の次の空港コレクションを記録するマップに置き換えることができます)
このコードは、再帰関数bool typeに戻り値を追加します。結果がtrueの場合、他の再帰は実行されません。これは、前のコードのfinish変数と同じです。
class Solution {
public:
vector<string> result;
vector<string> path;
vector<string> findItinerary(vector<vector<string>>& tickets) {
sort(tickets.begin(), tickets.end());
vector<bool> used(tickets.size(), false);
path.push_back("JFK");
back(tickets, used);
return result;
}
bool back(const vector<vector<string>>& tickets, vector<bool>& used) {
if (path.size() == tickets.size() + 1) {
result = path;
return true;
}
for (int i = 0; i < tickets.size(); i++) {
if (used[i] || tickets[i][0] != path[path.size()-1]) continue;
used[i] = true;
path.push_back(tickets[i][1]);
if (back(tickets, used)) return true;
path.pop_back();
used[i] = false;
}
return false;
}
};