[欧拉路]合法重新排列数对

6 篇文章 0 订阅

题目描述

给你一个下标从 0 开始的二维整数数组 pairs ,其中 pairs[i] = [starti, endi] 。如果 pairs 的一个重新排列,满足对每一个下标 i ( 1 <= i < pairs.length )都有 endi-1 == starti ,那么我们就认为这个重新排列是 pairs 的一个 合法重新排列 。

请你返回 任意一个 pairs 的合法重新排列。

注意:数据保证至少存在一个 pairs 的合法重新排列。

思路分析

  • 入度为2时,从出度为1的结点开始,入度为0任选结点
  • 逆向输出各结点
  • circuit保存当前走到死胡同的一组连接的结点

  • curr_path的top就是当前可以继续展开bfs搜索的当前主线的结尾结点

堆栈写法代码如下

 

class Solution {
public:
    vector<int> printCircuit(int curr,map<int,vector<int>> adj){
        // adj represents the adjacency list of
        // the directed graph
        // edge_count represents the number of edges
        // emerging from a vertex
        unordered_map<int,int> edge_count;

        for (auto &i:adj)
            //find the count of edges to keep track
            //of unused edges
            edge_count[i.first] = i.second.size();   //对应下标取边数

        // Maintain a stack to keep vertices
        stack<int> curr_path;

        // vector to store final circuit
        vector<int> circuit;

        // start from any vertex
        curr_path.push(curr);
        int curr_v = curr; // Current vertex

        while (!curr_path.empty())
        {
            // If there's remaining edge
            if (edge_count[curr_v]){
                // Push the vertex
                curr_path.push(curr_v);

                // Find the next vertex using an edge
                int next_v = adj[curr_v].back();  //每次从最后一个元素取(考虑时间复杂度)

                // and remove that edge
                edge_count[curr_v]--;
                adj[curr_v].pop_back();

                // Move to next vertex
                curr_v = next_v;
            }

                // back-track to find remaining circuit
            else    //到最后也会重复执行这一过程
            {
                circuit.push_back(curr_v);   //保留在回路中

                // Back-tracking
                curr_v = curr_path.top(); //获取当前元素
                curr_path.pop();    //还要退栈
            }
        }
        reverse(circuit.begin(),circuit.end());
        return circuit;
    }
    vector<vector<int>> validArrangement(vector<vector<int>>& pairs) {
        map<int,vector<int>> adj;
        map<int,pair<int,int>> mp; //统计所有点的入度和出度
        int curr=pairs[0][0];
        for(auto &t:pairs){
            adj[t[0]].push_back(t[1]);
            mp[t[0]].second++; mp[t[1]].first++;
        }
        for(auto &t:mp)
            if((t.second.second-t.second.first)==1) curr=t.first;
        vector<int> c=printCircuit(curr,adj);
        
        vector<vector<int>> p;
        for(int i=0;i<c.size()-1;i++)
            p.push_back({c[i],c[i+1]});
        return p;
    }
};

dfs方法如下,但容易爆栈

class Solution {
public:
    vector<vector<int>> validArrangement(vector<vector<int>>& pairs) {
        map<int,vector<int>> adj;
        map<int,pair<int,int>> mp; //统计所有点的入度和出度
        int curr=pairs[0][0];
        for(auto &t:pairs){
            adj[t[0]].push_back(t[1]);
            mp[t[0]].second++; mp[t[1]].first++;
        }
        for(auto &t:mp)
            if((t.second.second-t.second.first)==1) curr=t.first;
        vector<vector<int>> p;
        function<void(int)> dfs = [&](int u) {
            while (!adj[u].empty()) {
                int v = adj[u].back();
                adj[u].pop_back();
                dfs(v);
                p.push_back({u, v});   //相当于之后的
            }
        };
        dfs(curr);
        reverse(p.begin(),p.end());
        return p;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值