给定Rooted树中可用的N个顶点的DFS遍历的开始和结束时间,任务是构造树(打印每个节点的父级)。
根节点的父级为0。
例子:
Input: Start[] = {2, 4, 1, 0, 3}, End[] = {3, 5, 4, 5, 4}
Output: 3 4 4 0 3
Given Tree is -:
4(0, 5)
/ \
(1, 4)3 2(4, 5)
/ \
(2, 3)1 5(3, 4)
The root will always have start time = 0
processing a node takes 1 unit time but backtracking
does not consume time, so the finishing time
of two nodes can be the same.
Input: Start[] = {4, 3, 2, 1, 0}, End[] = {5, 5, 3, 3, 5}
Output: 2 5 4 5 0
方法:
- 树的根是起始时间为零的顶点。
- 现在,找到一个顶点的子代就足够了,这样我们就可以找到每个顶点的父代。
- 将Identity [i]定义为以i开头的顶点的索引。
- 由于Start [v]和End [v]是顶点v的开始和结束时间。v的第一个子代是Identity [Start [v] +1]和
第(i + 1)个是Identity [End [chv [i]]],其中chv [i]是v的第i个子代。 - 以DFS方式遍历并更新每个节点的父节点。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
int N;
// Function to find the parent of each node.
vector Restore_Tree(int Start[], int End[])
{
// Storing index of vertex with starting
// time Equal to i
vector Identity(N,0);
for (int i = 0; i < N; i++)
{
Identity[Start[i]] = i;
}
// Parent array
vector parent(N,-1);
int curr_parent = Identity[0];
for (int j = 1; j < N; j++)
{
// Find the vertex with starting time j
int child = Identity[j];
// If end time of this child is greater than
// (start time + 1), then we traverse down and
// store curr_parent as the parent of child
if (End[child] - j > 1)
{
parent[child] = curr_parent;
curr_parent = child;
}
// Find the parent of current vertex
// over iterating on the finish time
else
parent[child] = curr_parent;
// Backtracking takes zero time
while (End[child]== End[parent[child]])
{
child = parent[child];
curr_parent = parent[child];
if (curr_parent == Identity[0])
break;
}
}
for (int i = 0; i < N; i++)
parent[i] += 1;
// Return the parent array
return parent;
}
// Driver Code
int main()
{
N = 5;
// Start and End time of DFS
int Start[] = {2, 4, 1, 0, 3};
int End[] = {3, 5, 4, 5, 4};
vector a = Restore_Tree(Start, End);
for(int ans:a)
cout << ans << " ";
return 0;
}
// This code is contributed by mohit kumar 29
Java
// Java implemenation of above approach
import java.util.Arrays;
class GFG
{
static int N = 5;
// Function to find the parent of each node.
static int[] Restore_Tree(int []S, int []End)
{
// Storing index of vertex with starting
// time Equal to i
int []Identity = new int[N];
for(int i = 0; i < N; i++)
Identity[S[i]] = i;
// Parent array
int []parent = new int[N];
Arrays.fill(parent,-1);
int curr_parent = Identity[0];
for(int j = 1; j < N; j++)
{
// Find the vertex with starting time j
int child = Identity[j];
// If end time of this child is greater than
// (start time + 1), then we traverse down and
// store curr_parent as the parent of child
if(End[child] - j > 1)
{
parent[child] = curr_parent;
curr_parent = child;
}
// Find the parent of current vertex
// over iterating on the finish time
else{
parent[child] = curr_parent;
// Backtracking takes zero time
while(parent[child]>-1 && End[child] == End[parent[child]])
{
child = parent[child];
curr_parent = parent[child];
if(curr_parent == Identity[0])
break;
}
}
}
for(int i = 0; i < N; i++)
parent[i] += 1;
// Return the parent array
return parent;
}
// Driver Code
public static void main(String[] args)
{
// Start and End time of DFS
int []Start = {2, 4, 1, 0, 3};
int []End = {3, 5, 4, 5, 4};
int ans[] =Restore_Tree(Start, End);
for(int a:ans)
System.out.print(a + " ");
}
}
// This code has been contributed by 29AjayKumar
Python
# Python implementation of the above approach
# Function to find the parent of each node.
def Restore_Tree(S, E):
# Storing index of vertex with starting
# time Equal to i
Identity = N*[0]
for i in range(N):
Identity[Start[i]] = i
# Parent array
parent = N*[-1]
curr_parent = Identity[0]
for j in range(1, N):
# Find the vertex with starting time j
child = Identity[j]
# If end time of this child is greater than
# (start time + 1), then we traverse down and
# store curr_parent as the parent of child
if End[child] - j > 1:
parent[child] = curr_parent
curr_parent = child
# Find the parent of current vertex
# over iterating on the finish time
else:
parent[child] = curr_parent
# Backtracking takes zero time
while End[child]== End[parent[child]]:
child = parent[child]
curr_parent = parent[child]
if curr_parent == Identity[0]:
break
for i in range(N):
parent[i]+= 1
# Return the parent array
return parent
# Driver Code
if __name__=="__main__":
N = 5
# Start and End time of DFS
Start = [2, 4, 1, 0, 3]
End = [3, 5, 4, 5, 4]
print(*Restore_Tree(Start, End))
C#
// C# implementation of the approach
using System;
class GFG
{
static int N = 5;
// Function to find the parent of each node.
static int[] Restore_Tree(int []S, int []End)
{
// Storing index of vertex with starting
// time Equal to i
int []Identity = new int[N];
for(int i = 0; i < N; i++)
Identity[S[i]] = i;
// Parent array
int []parent = new int[N];
for(int i = 0; i < N; i++)
parent[i]=-1;
int curr_parent = Identity[0];
for(int j = 1; j < N; j++)
{
// Find the vertex with starting time j
int child = Identity[j];
// If end time of this child is greater than
// (start time + 1), then we traverse down and
// store curr_parent as the parent of child
if(End[child] - j > 1)
{
parent[child] = curr_parent;
curr_parent = child;
}
// Find the parent of current vertex
// over iterating on the finish time
else
{
parent[child] = curr_parent;
// Backtracking takes zero time
while(parent[child]>-1 && End[child] == End[parent[child]])
{
child = parent[child];
curr_parent = parent[child];
if(curr_parent == Identity[0])
break;
}
}
}
for(int i = 0; i < N; i++)
parent[i] += 1;
// Return the parent array
return parent;
}
// Driver Code
public static void Main(String[] args)
{
// Start and End time of DFS
int []Start = {2, 4, 1, 0, 3};
int []End = {3, 5, 4, 5, 4};
int []ans =Restore_Tree(Start, End);
foreach(int a in ans)
Console.Write(a + " ");
}
}
/* This code contributed by PrinciRaj1992 */
输出:
3 4 4 0 3
时间复杂度: O(N)
其中N是树中的节点数。