日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

332. 重新安排行程(回溯算法)

發(fā)布時(shí)間:2025/3/21 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 332. 重新安排行程(回溯算法) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

給你一份航線列表 tickets ,其中 tickets[i] = [fromi, toi] 表示飛機(jī)出發(fā)和降落的機(jī)場(chǎng)地點(diǎn)。請(qǐng)你對(duì)該行程進(jìn)行重新規(guī)劃排序。

所有這些機(jī)票都屬于一個(gè)從 JFK(肯尼迪國(guó)際機(jī)場(chǎng))出發(fā)的先生,所以該行程必須從 JFK 開(kāi)始。如果存在多種有效的行程,請(qǐng)你按字典排序返回最小的行程組合。

例如,行程 [“JFK”, “LGA”] 與 [“JFK”, “LGB”] 相比就更小,排序更靠前。
假定所有機(jī)票至少存在一種合理的行程。且所有的機(jī)票 必須都用一次 且 只能用一次。

示例 1:

輸入:tickets = [[“MUC”,“LHR”],[“JFK”,“MUC”],[“SFO”,“SJC”],[“LHR”,“SFO”]]
輸出:[“JFK”,“MUC”,“LHR”,“SFO”,“SJC”]

示例 2:

輸入:tickets = [[“JFK”,“SFO”],[“JFK”,“ATL”],[“SFO”,“ATL”],[“ATL”,“JFK”],[“ATL”,“SFO”]]
輸出:[“JFK”,“ATL”,“JFK”,“SFO”,“ATL”,“SFO”]
解釋:另一種有效的行程是 [“JFK”,“SFO”,“ATL”,“JFK”,“ATL”,“SFO”] ,但是它字典排序更大更靠后。

提示:

1 <= tickets.length <= 300
tickets[i].length == 2
fromi.length == 3
toi.length == 3 fromi 和 toi 由大寫英文字母組成
fromi != toi

這道題其實(shí)是一道深搜的題目,但是回溯實(shí)際上就是用到了深搜,這個(gè)題目中同樣也有回溯;

這個(gè)題目可能遇到的幾個(gè)主要問(wèn)題及解析如下,

1,一個(gè)行程中,如果航班處理不好容易變成一個(gè)圈,成為死循環(huán)
為了避免這個(gè)情況,我們需要對(duì)每一個(gè)機(jī)場(chǎng)進(jìn)行一個(gè)計(jì)數(shù),走一次減一次,如果出現(xiàn)次數(shù)為0或小于0次,就說(shuō)明走過(guò)了這個(gè)機(jī)場(chǎng),就不能再走了,不然就會(huì)出現(xiàn)這個(gè)情況;

2,有多種解法,但是題目要字母序靠前排在前面,如何該記錄映射關(guān)系呢 ?
一個(gè)機(jī)場(chǎng)可以映射多個(gè)機(jī)場(chǎng),所以可以用unordered_map容器,字母排序則需要一個(gè)map容器,這樣就可以通過(guò)出發(fā)的機(jī)場(chǎng)找到排序后的可以到達(dá)的機(jī)場(chǎng)了;

3,使用回溯法(也可以說(shuō)深搜) 的話,那么終止條件是什么呢?
因?yàn)橐婚_(kāi)始一定會(huì)在JFK機(jī)場(chǎng),然后通過(guò)的機(jī)場(chǎng)數(shù)就是所有的tickets數(shù)目,所以一旦走的航線數(shù)目等于tickets + 1時(shí)(這個(gè)1就是JFK起始機(jī)場(chǎng))就可以結(jié)束;

4,搜索的過(guò)程中,如何遍歷一個(gè)機(jī)場(chǎng)所對(duì)應(yīng)的所有機(jī)場(chǎng)?
這就需要對(duì)set和map非常非常熟悉了,這里選用的就是unordered_map容器和map容器,這里的映射關(guān)系如下:
unordered_map:
key:當(dāng)前所處的機(jī)場(chǎng)(string)
value:當(dāng)前所處的機(jī)場(chǎng)能到達(dá)所有機(jī)場(chǎng)(map)

map:
key:所能到達(dá)的機(jī)場(chǎng)(string)
value:所到達(dá)的機(jī)場(chǎng)出現(xiàn)次數(shù)(int)

所以這里就稍微復(fù)雜一點(diǎn),我們代碼中定義為:unordered_map<string, map<string, int>> targets;

這就是主要會(huì)遇到的問(wèn)題,代碼里還有詳細(xì)注釋,可以結(jié)合理解
代碼如下:

class Solution { private:// unordered_map<出發(fā)機(jī)場(chǎng), map<到達(dá)機(jī)場(chǎng), 航班次數(shù)>> targetsunordered_map<string, map<string, int>> targets;bool backTacking(int ticketSize, vector<string>& ans) {if (ans.size() == ticketSize + 1) {return true;}//這個(gè)for循環(huán)為了遍歷此時(shí)到達(dá)的機(jī)場(chǎng)所有的航班次數(shù)//targets[ans[ans.size - 1]]就是targets[此時(shí)到達(dá)的機(jī)場(chǎng)]//這時(shí)到達(dá)的機(jī)場(chǎng)可以說(shuō)就是新的出發(fā)機(jī)場(chǎng),就是看看能從這到哪些地方//這里的pair<const string, int>可以改成auto,但是為了方便理解,這里就寫了原格式for (pair<const string, int>& i : targets[ans[ans.size() - 1]]) {//如果此時(shí)到達(dá)的機(jī)場(chǎng)沒(méi)有來(lái)過(guò),繼續(xù)執(zhí)行//如果此時(shí)到達(dá)的機(jī)場(chǎng)來(lái)過(guò),即i.second <= 0,那么就直接跳過(guò),防止出現(xiàn)死循環(huán)if (i.second > 0) {ans.push_back(i.first);i.second--;if (backTacking(ticketSize, ans)) return true;ans.pop_back();i.second++;}}return false;} public:vector<string> findItinerary(vector<vector<string>>& tickets) {vector<string> ans;//記錄每一個(gè)出發(fā)機(jī)場(chǎng)到所能到達(dá)的機(jī)場(chǎng)的航班次數(shù)for (auto i : tickets) {targets[i[0]][i[1]]++;}//起始行程必須從JFK開(kāi)始ans.push_back("JFK");backTacking(tickets.size(), ans);return ans;} };

這道題對(duì)容器選擇和應(yīng)用上是主要難點(diǎn);

總結(jié)

以上是生活随笔為你收集整理的332. 重新安排行程(回溯算法)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。