332. Reconstruct Itinerary

仅供自己学习

 

思路:

一开始就是往这DFS直接做就可以了,但是看了题解,原来这么复杂的吗?

DFS:把tickets的数据放入图,然后直接对每个结点DFS即可。这里有一个问题,记住题目前提是一定会有可行解,但如果有孤岛例子的话,例如图 [["JFK","KUL"]["JFK","NRT"]["NRT","JFK"]],此时如果用DFS,会把孤岛KUL加进来,这样就死路了,但又因为是DFS我们得到的结果是逆序的,在最后将结果反转即可,这样KUL就会在最后,即最后一个走的。因为是必会有可行解,所以不会存在 [["JFK","KUL"]["JFK","NRT"]["KUL","JFK"]],因为这样无解。

整个图用unordered_map存,又因为要按字母序取,所以我们采用multiset的数据结构存储邻居结点,整体就是unordered_map<string,multiset<string>>,之后把tickets的数据放入图中,然后调用DFS

DFS中执行对当前飞机场的下一站飞机场又进行DFS,每探索一个飞机场就把其从multiset中删掉,然后对其调用DFS,当所有的下一站探索结束后就把该站加入 result vector中。

代码:

 1 class Solution {
 2 public:
 3     void DFS(unordered_map<string,multiset<string>>& m,string s,vector<string>& res){
 4         while(m[s].size()){
 5             string temp= *m[s].begin();
 6             m[s].erase(m[s].begin());
 7             DFS(m,temp,res);
 8         }
 9         res.push_back(s);
10     }
11 
12     vector<string> findItinerary(vector<vector<string>>& tickets) {
13         vector<string> res;
14         unordered_map<string,multiset<string>> m;
15         for(const auto& s:tickets){
16             m[s[0]].insert(s[1]);
17         }
18         DFS(m,"JFK",res);
19         return vector<string> (res.rbegin(),res.rend());
20     }
21 };

 

这是递归调用的DFS,下面是用栈的DFS,思路是一样的。

 1 class Solution {
 2 public:
 3     vector<string> findItinerary(vector<vector<string>>& tickets) {
 4         vector<string> res;
 5         unordered_map<string,multiset<string>> m;
 6         stack<string> s({"JFK"});
 7         for(auto k:tickets){
 8             m[k[0]].insert(k[1]);
 9         }
10         while(!s.empty()){
11             string temp=s.top();
12             if(!m[temp].empty()){            
13                 s.push(*m[temp].begin());
14                 m[temp].erase(m[temp].begin());
15             }
16             else{
17                 res.insert(res.begin(),temp);
18                 s.pop();
19 
20             }
21             
22         }
23         return res;
24     }
25 };

 

暂留问题 12-18行改成

1 while(!m[temp].empty()){            
2       s.push(*m[temp].begin());
3       m[temp].erase(m[temp].begin());
4           }
5 res.insert(res.begin(),temp);
6 s.pop();         

会无法得到正确答案?

 

在unordered_map的value的数据结构还可用priority_queue,它是基于堆的数据结构,并且可自行决定按照降序排序或升序排序,取出的时间复杂度为O(1),,删除时间复杂度为O(logn),其余的与上述一样

 

代码:

 1 class Solution {
 2 public:
 3     unordered_map<string,priority_queue<string,vector<string>,std::greater<string>>> m;
 4     vector<string> res;
 5     void dfs(const string& p){
 6         while(m.count(p)&&m[p].size()){
 7             string tmp=m[p].top();
 8             m[p].pop();
 9             dfs(tmp);
10         }
11         res.insert(res.begin(),p);
12     }
13     vector<string> findItinerary(vector<vector<string>>& tickets) {
14         for(const auto& ex:tickets){
15             m[ex[0]].push(ex[1]);
16         }
17         dfs("JFK");
18         return res;
19     }
20 };

 

posted @ 2021-03-01 23:35  Mrsdwang  阅读(64)  评论(0)    收藏  举报