Problem of the day
You are given a 2-d integer array (0-based indexing) “pairs”, where pairs[i] = [ starti, endi ]. Your task is to arrange the given pairs such that for every ‘i’ where 1 <= i <= pairs.length, the endi-1 is equal to starti
Note:The input is generated in such a way that the answer always exists.
If there are multiple answers print any of them.
Example:
If pairs = [ [1,2] , [3,1] , [2,3] ] then the following arrangement is valid:
Arrangement = [ [1,2] , [2,3] , [3,1] ] here, you can see for every ‘i’ where 1 <= i <= 2, the endi-1 is equal to starti
The first line contains an Integer 'T' which denotes the number of test cases or queries to be run. Then the test cases follow.
The first line of each test case contains a single integer ‘N’, denoting the number of pairs.
Then next ‘N’ lines follow in each test case. The ith line consists of two space-separated integers ‘start’ and ‘end’ representing the start and end of the ith pair.
Output Format :
For each test case, print the ‘N’ lines. The ith line consists of two space-separated integers ‘start’ and ‘end’ representing the start and end of the arranged pair.
Print a separate line for each test case.
Note :
You do not need to print anything, it has already been taken care of. Just implement the given function.
1 <= T <= 10
1 <= N <= 5 * 10^4
0 <= start , end <= 10^9
starti != endi
No two pairs are exactly the same.
Time limit: 1 sec
2
3
1 2
3 1
2 3
1
1 2
1 2
2 3
3 1
1 2
For the first test case, pairs = [ [1,2] , [3,1] , [2,3] ] then the following arrangement is valid:
Arrangement = [ [1,2] , [2,3] , [3,1] ] here, you can see for every ‘i’ where 1 <= i <= 2, the endi-1 is equal to start
For the second test case, pairs = [1,2], here the given pair is itself a valid pair.
2
4
1 2
4 5
2 3
3 4
5
1 2
4 5
2 3
3 4
5 1
1 2
2 3
3 4
4 5
1 2
2 3
3 4
4 5
5 1
Consider every pairs[i] as the directed edge and think of the Euler path in directed graphs.
Approach:
In this problem we can consider every pairs[i] as the directed edge from the node pairs[i][0] to the node pairs[i][1]. As all the pairs[i] are distinct from each other and you have to find a valid arrangement of pairs, this means that every edge should be used exactly once.
The given problem can be boiled down to the following problem:
You are given a directed graph and you have to find an Euler path in this graph. An Euler path is a path that uses every edge of a graph exactly once. Also, it is given that the answer always exists means that the Euler path always exists in the given graph.
The first thing we have to do is to create an adjacency list of every node, here we don’t know about the range of the nodes so we will use unordered_map to store the adjacency list of every node, after that, we have created the adjacency list of every node, we will maintain the “in” and “out” degree of every node, “in” degree of a node is the number of edges coming towards the node and “out” degree of a node is the number of edges going from the node.
For finding the Euler path we have to first find the starting node from which we will start the dfs traversal. A valid start node for finding the Euler path is the node which has outDegree- inDegree is equal to 1, and the count of this node will be at most one. If a graph has no such node then we can start from any node in the graph. In the dfs(node, adj, out, path) where “node” is the current node, we are at, “adj” is the adjacency list of all the nodes, adjacency list stores all the nodes which are directly connected to the ith node, “out” is the vector which stores the out-degree of every node, “path” is the vector which stores the Euler path.
The idea is to start the dfs from the “start” node and just start traversing the edges which are not visited yet after a point we will be at a node “x” which has no out-edge left so, we will push that node into “path” vector and then backtrack to a node which has an out-edge.
For checking whether a node has an out-edge or not we will use “out” vector after we reach any node let’s say “x” we will check whether out[x] is equal to zero or not, if it is zero then we will push the node into “path” vector otherwise we will update out[x] = out[x] - 1 and then call the dfs function from the node adj[x][out[x]], here you can see out[x] acts as an index in the adjacency list of the node “x”, every time it will decrease by 1 thus, we can say that every time we will have a unique edge.
Here is the algorithm:
O( N ), where ‘N’ is the number of pairs given.
We are touching every edge exactly once and there are ‘N’ number of edges and we are using unordered maps which have lookups in O(1) time and creating an adjacency list will also take O( N ) time, Thus overall time complexity will be O(N).
O( N ), where ‘N’ is the number of pairs given.
Extra space used by adjacency list “ADJ” is of size O( N ), and recursion stack, “path”, “ans”, “in”, “out” use O(N) space, Thus overall space complexity will be O( N ).