[Leetcode]2097.合法重新排列数对

【题目描述】

力扣icon-default.png?t=LA92https://leetcode-cn.com/problems/valid-arrangement-of-pairs/

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

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

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

示例 1:

输入:pairs = [[5,1],[4,5],[11,9],[9,4]]
输出:[[11,9],[9,4],[4,5],[5,1]]
解释:
输出的是一个合法重新排列,因为每一个 endi-1 都等于 starti 。
end0 = 9 == 9 = start1 
end1 = 4 == 4 = start2
end2 = 5 == 5 = start3
示例 2:

输入:pairs = [[1,3],[3,2],[2,1]]
输出:[[1,3],[3,2],[2,1]]
解释:
输出的是一个合法重新排列,因为每一个 endi-1 都等于 starti 。
end0 = 3 == 3 = start1
end1 = 2 == 2 = start2
重新排列后的数组 [[2,1],[1,3],[3,2]] 和 [[3,2],[2,1],[1,3]] 都是合法的。
示例 3:

输入:pairs = [[1,2],[1,3],[2,1]]
输出:[[1,2],[2,1],[1,3]]
解释:
输出的是一个合法重新排列,因为每一个 endi-1 都等于 starti 。
end0 = 2 == 2 = start1
end1 = 1 == 1 = start2
 

提示:

1 <= pairs.length <= 105
pairs[i].length == 2
0 <= starti, endi <= 109
starti != endi
pairs 中不存在一模一样的数对。
至少 存在 一个合法的 pairs 重新排列。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-arrangement-of-pairs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

【题目分析】

分析题目,一个合法的排列其实就是寻找一条路径经过图中的每个顶点,且经过每一条边,且每条边已经过一次;

其实是求一条欧拉通路,欧拉通路的定义:经过图中每个顶点,且经过每条边一次;

起点满足:出度 = 入度 + 1

终点满足:入度 = 出度 + 1

此题是有向图的遍历,首先是构图:可以采用邻接矩阵;

然后采用DFS从起点开始进行遍历;

由于DFS是自底向上的,所以需要对结果进行逆序排列;

【代码如下】

class Solution {
public:
    vector<vector<int>> validArrangement(vector<vector<int>>& pairs) {
        vector<vector<int>> res;
        map<int, vector<int>> mv;
        map<int, int> inDegree;
        map<int, int> outDegree;
        for (auto& p : pairs) {
            outDegree[p[0]]++;
            inDegree[p[1]]++;
            mv[p[0]].emplace_back(p[1]);
        }
        int start = pairs[0][0];
        for (auto& p : pairs) {
            if (outDegree[p[0]] == inDegree[p[0]] + 1) {
                start = p[0];
                break;
            }
        }
        function<void(int)> DFS = [&](int start) {
            while (!mv[start].empty()) {
                int n = mv[start].back();
                mv[start].pop_back();
                DFS(n);
                //std::cout << start << n << std::endl;
                res.push_back({start, n});
            }
        };
        DFS(start);
        reverse(res.begin(), res.end());
        return res;
    }
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值