Given a Graph having N+1 nodes with 2*N-1 edges and a boolean array arr[ ], the task is to find if one can visit every nodes exactly once and print any one possible path. It's also known that N-1 edges go i-th to (i+1)-th node and rest edges go i-th to (n+1)-th node if arr[i] is 0 otherwise (n+1)-th to i-th.
Examples:
Input: N = 3, arr = {0, 1, 0}
Output: [1, 2, 3, 4]
Explanation:
from the given data, the edges will:
1 -> 2
2 -> 3
1 -> 4
4 -> 2
3 -> 4Therefore, one can follow the path: 1 -> 2 -> 3 -> 4
Input: N = 4, arr = {0, 1, 1, 1}
Output: [1, 4, 2, 3]
Approach: This problem can be solved using greedy approach with some observations. The observations are given below:
- If arr[1] is 1, then follow the path [N+1 -> 1 -> 2........-> N].
- If arr[N] is 0, then follow the path [1 -> 2 ->..........-> N -> N+1].
- If arr[1] is 0 and arr[N] is 1, there must exists an integer i (1 ≤ i< N) where arr[i] =0 and arr[i+1] = 1, then the path [1 -> 2 -> ⋯ -> i -> N+1 -> i+1 -> i+2 -> ⋯N] is valid.
- Previous step proves that there always exists an Hamiltonian path in this graph.
Below is the implementation for the above approach:
// C++ program for above approach.
#include <bits/stdc++.h>
using namespace std;
// Function to find print path
void findpath(int N, int a[])
{
// If a[0] is 1
if (a[0]) {
// Printing path
cout <<" "<< N + 1;
for (int i = 1; i <= N; i++)
cout <<" " << i;
return;
}
// Seeking for a[i] = 0 and a[i+1] = 1
for (int i = 0; i < N - 1; i++) {
if (!a[i] && a[i + 1]) {
// Printing path
for (int j = 1; j <= i; j++)
cout <<" "<< j;
cout <<" "<< N + 1;
for (int j = i + 1; j <= N; j++)
cout <<" "<< j;
return;
}
}
// If a[N-1] = 0
for (int i = 1; i <= N; i++)
cout <<" "<< i;
cout <<" "<< N + 1;
}
// Driver Code
int main()
{
// Given Input
int N = 3, arr[] = { 0, 1, 0 };
// Function Call
findpath(N, arr);
}
// This code is contributed by shivanisinghss2110
// C++ program for above approach.
#include <bits/stdc++.h>
using namespace std;
// Function to find print path
void findpath(int N, int a[])
{
// If a[0] is 1
if (a[0]) {
// Printing path
printf("%d ", N + 1);
for (int i = 1; i <= N; i++)
printf("%d ", i);
return;
}
// Seeking for a[i] = 0 and a[i+1] = 1
for (int i = 0; i < N - 1; i++) {
if (!a[i] && a[i + 1]) {
// Printing path
for (int j = 1; j <= i; j++)
printf("%d ", j);
printf("%d ", N + 1);
for (int j = i + 1; j <= N; j++)
printf("%d ", j);
return;
}
}
// If a[N-1] = 0
for (int i = 1; i <= N; i++)
printf("%d ", i);
printf("%d ", N + 1);
}
// Driver Code
int main()
{
// Given Input
int N = 3, arr[] = { 0, 1, 0 };
// Function Call
findpath(N, arr);
}
// Java program for the above approach
import java.io.*;
class GFG {
// Function to find print path
static void findpath(int N, int a[])
{
// If a[0] is 1
if (a[0] == 1) {
// Printing path
System.out.print((N + 1) + " ");
for (int i = 1; i <= N; i++)
System.out.print((i) + " ");
return;
}
// Seeking for a[i] = 0 and a[i+1] = 1
for (int i = 0; i < N - 1; i++) {
if (a[i] == 0 && a[i + 1] == 1) {
// Printing path
for (int j = 1; j <= i; j++)
System.out.print((j) + " ");
System.out.print((N + 1) + " ");
for (int j = i + 1; j <= N; j++)
System.out.print((j) + " ");
return;
}
}
// If a[N-1] = 0
for (int i = 1; i <= N; i++)
System.out.print((i) + " ");
System.out.print((N + 1) + " ");
}
// Driver Code
public static void main(String[] args)
{
int N = 3, arr[] = { 0, 1, 0 };
// Function Call
findpath(N, arr);
}
}
// This code is contributed by dwivediyash
# Python 3 program for above approach.
# Function to find print path
def findpath(N, a):
# If a[0] is 1
if (a[0]):
# Printing path
print(N + 1)
for i in range(1,N+1,1):
print(i,end = " ")
return
# Seeking for a[i] = 0 and a[i+1] = 1
for i in range(N - 1):
if (a[i]==0 and a[i + 1]):
# Printing path
for j in range(1,i+1,1):
print(j,end = " ")
print(N + 1,end = " ");
for j in range(i + 1,N+1,1):
print(j,end = " ")
return
# If a[N-1] = 0
for i in range(1,N+1,1):
print(i,end = " ")
print(N + 1,end = " ")
# Driver Code
if __name__ == '__main__':
# Given Input
N = 3
arr = [0, 1, 0]
# Function Call
findpath(N, arr)
# This code is contributed by ipg2016107.
// C# program for above approach.
using System;
class GFG{
// Function to find print path
static void findpath(int N, int []a)
{
// If a[0] is 1
if (a[0]!=0) {
// Printing path
Console.Write(N + 1);
for (int i = 1; i <= N; i++)
Console.Write(i+ " ");
return;
}
// Seeking for a[i] = 0 and a[i+1] = 1
for (int i = 0; i < N - 1; i++) {
if (a[i]==0 && a[i + 1] !=0) {
// Printing path
for (int j = 1; j <= i; j++)
Console.Write(j+" ");
Console.Write(N + 1 + " ");
for (int j = i + 1; j <= N; j++)
Console.Write(j + " ");
return;
}
}
// If a[N-1] = 0
for (int i = 1; i <= N; i++)
Console.Write(i+" ");
Console.Write(N + 1 + " ");
}
// Driver Code
public static void Main()
{
// Given Input
int N = 3;
int []arr = { 0, 1, 0 };
// Function Call
findpath(N, arr);
}
}
// This code is contributed by SURENDRA_GANGWAR.
<script>
// JavaScript Program to implement
// the above approach
// Function to find print path
function findpath(N, a) {
// If a[0] is 1
if (a[0]) {
// Printing path
document.write(N + 1);
for (let i = 1; i <= N; i++)
document.write(i);
return;
}
// Seeking for a[i] = 0 and a[i+1] = 1
for (let i = 0; i < N - 1; i++) {
if (!a[i] && a[i + 1]) {
// Printing path
for (let j = 1; j <= i; j++)
document.write(j+" ");
document.write(N + 1+" ");
for (let j = i + 1; j <= N; j++)
document.write(j+" ");
return;
}
}
// If a[N-1] = 0
for (let i = 1; i <= N; i++)
document.write(i+" ");
document.write(N + 1+" ");
}
// Driver Code
// Given Input
let N = 3, arr = [0, 1, 0];
// Function Call
findpath(N, arr);
// This code is contributed by Potta Lokesh
</script>
Output:
4 1 2 3
Time Complexity: O(N)
Auxiliary Space: O(1)