LeetCode 5932. 合法重新排列数对

给你一个下标从 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.对于无向图G,当图是连通的,且没有奇点,那么G是欧拉图

2.对于无向图G,当图是连通的,且有2个奇点,那么G是半欧拉图

3.对于有向图G,当图书连通的,且每个顶点的出度等于入度,那么G是欧拉图

4.对于有向图G,当图书连通的,且只有一个顶点的出度等于入度+1,只有一个顶点的入度等于出度+1,其余顶点出度等于入度,那么G是半欧拉图。

Hierholzer 算法解决本质就是一种的回溯。

其流程如下:

1.从起点出发进行深度优先搜索;

2.每经过一条边就将边删除;

3.当一个顶点没有边的时候就将该顶点加入到栈中。

最后将栈反转就是一条欧拉路径。

class Solution {
	vector<vector<int>> ans;
	void dfs(int u, unordered_map<int, vector<int>> &ma)
	{
		while (!ma[u].empty())
		{
			int v = ma[u].back();
			ma[u].pop_back();
			dfs(v, ma);
			ans.push_back({ u, v });
		}
	}

public:
	vector<vector<int>> validArrangement(vector<vector<int>>& pairs) {
		unordered_map<int, vector<int>> ma;
		unordered_map<int, int> ind, outd;
		for (auto &pair : pairs)
		{
			int u = pair[0], v=pair[1];
			ma[u].push_back(v);
			++ind[v], ++outd[u];
		}
		int start = pairs[0][0];     //初始点
		for (auto &out : outd)
		{
			if (out.second == ind[out.first] + 1)
			{
				start = out.first;
				break;
			}
		}
		dfs(start, ma);
		reverse(ans.begin(), ans.end());
		return ans;

	}
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值