Leetcode题解系列——Reconstruct Itinerary(c++版)

版权声明: https://blog.csdn.net/dickdick111/article/details/82844986

题目链接:332. Reconstruct Itinerary

题目大意:给出一个结点对的集合,结点对中为飞机的起飞点与降落点。要求根据飞机机票的信息来重新构造出旅途的线路,即遍历这个图。

注意点:

  1. 题目给出一定会存在一个解,即构造的图一定是连通的。
  2. 这是一个有向图,要注意起始与结束地点
  3. 与一般的深度搜索不同,这次我们不是要搜索结点的访问次序,而是搜索边的访问次序。这就意味着结点可以重复访问,而每条边只能访问一次。
  4. 若有多种路线可选时候,题目要求输出字典序最小的一条路线,这就要用到集合multiset或者优先队列等数据结构来存储这个图。

一.算法设计

显然这是一道图的深度搜索题目,且要针对图的每一条都搜索一次,找出字典序最小的路线。首先,我们要根据结点对来构建出图,可以用邻接表来表示图。由于方便比较字典序,这里我使用了multiset来储存每一个结点能到达的结点,以此达到建图的目的。

其次,根据深度搜索的思想,我们每遍历到的结点或者边应该设置一个标记表示访问结束,下次不再重复访问。而在本道题目中,可以将已经访问过的边的移出集合,每一次只对集合中仅剩的元素进行遍历。当集合无元素的时候,证明已经到达搜索的最深处,将结点的值保留在vector中用以输出。

由于,根据递归我们得到的序列是从最深处再回溯到起始点,所以在输出的时候要将vector的元素反转输出,从而得到重构的旅途线路。


二.代码实现

class Solution {
public:
    vector<string> findItinerary(vector<pair<string, string>> tickets) {
    	//建立邻接表,构造图
        std::map<string, multiset<string>> m;
        //存储路径,用于输出
        std::vector<string> v;
        for(int i = 0; i < tickets.size(); i++){
        	m[tickets[i].first].insert(tickets[i].second);
        }
        string start = "JFK";
        dfs(start, m, v);
        return vector<string>(v.rbegin(),v.rend());
    }

    void dfs(string start, map<string, multiset<string>>& m, std::vector<string>& v){
    	while(m[start].size() > 0){
    		string str = *(m[start].begin()); //拿取头元素
    		m[start].erase(m[start].begin());
    		dfs(str,m,v);
    	}
        v.push_back(start);
    }
};

三.改进方法

既然我们可以利用multiset来进行排序,也可以用优先队列来处理。leetcode给的展示代码就是用的这一种数据结构,除此之外还利用了auto的c++11属性来简化迭代子。

class Solution {
    
private:
    
        unordered_map<string, priority_queue<string, vector<string>, greater<string>>> graph;
        vector<string> result;
        void dfs(string vtex)
        {
            auto & edges = graph[vtex];
            while (!edges.empty())
            {
                string to_vtex = edges.top();
                edges.pop();
                dfs(to_vtex);
            }
            result.push_back(vtex);
        }
    
public:
    vector<string> findItinerary(vector<pair<string, string>> tickets) {
            for (auto e : tickets)
                graph[e.first].push(e.second);
            dfs("JFK");
            reverse(result.begin(), result.end());
            return result;
    }
};

猜你喜欢

转载自blog.csdn.net/dickdick111/article/details/82844986