给你一个下标从 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;
}
};