Given a linked list representing a graph with directed edges, check whether the given linked list is a Bipartite graph or not.
Examples:
Input: 1->2->3->4->NULL
Output: Possible
Explanation: It is possible to color the above linked list using 2 colors. We can color node 1 and 3 with one color and node 2 and 4 with other color.Input: 1->2->3->4->2
Output: Not Possible
Explanation: It is impossible to color the above linked list using 2 colors. We can try to color node 1 and 3 with one color and node 2 and 4 with other color but node 2 and 4 are adjacent nodes and cannot share the same color.
Approach: The problem can be solved using the following approach:
A singly linked list can be divided into two categories i.e. linked list with cycles and linked list without cycles. So if the linked list does not contains cycles then we can easily color all the alternate nodes with same color. But, when it contains cycle then it might happen that adjacent nodes share the same color. If we observe the length of cycle present in linked list then we can see that if the number of nodes in cycle is even then it is possible to color all the alternate nodes with same color else its impossible as there will always be two adjacent nodes which share the same color.
Steps to solve the problem:
- Use Floyd’s Cycle Detection Algorithm to detect if there is a loop present in the linked list.
- If no loop is present, return true
-
If a loop is present
- initialize a variable cnt = 0 to count the number of nodes in the cycle.
- Store the current node as curr_node.
- Now, move to the next node and increment cnt by 1.
- If the node is same as curr_node, then we have found the length of the cycle, else move to the next node.
- If the length of cycle is even return true, else return false.
Below is the implementation for the above approach:
// C++ code for the above approach: #include <bits/stdc++.h> using namespace std;
// Link list node class Node {
public :
int data;
Node* next;
Node( int val)
{
data = val;
next = NULL;
}
}; // Returns Node inside cycle if there is a // loop in linked list else returns NULL Node* detectLoop(Node* head) { // Floyd's Algorithm
Node *slow = head, *fast = head;
do {
slow = slow->next;
fast = fast->next->next;
} while (fast && fast->next && slow != fast);
if (!fast || !fast->next)
return NULL;
return slow;
} // Function which checks whether the list is // bipartite or not bool checkBipartiteList(Node* head)
{ Node* curr_node = detectLoop(head);
// If there is no loop, then current
// will contain NULL
if (!curr_node)
return true ;
// If there is a loop, then current will
// contain a node which is inside cycle
Node* temp = curr_node;
// Variable to store the length of the cycle
int cnt = 0;
do {
temp = temp->next;
cnt += 1;
} while (temp != curr_node);
return cnt % 2 == 0;
} // Driver program to test above function int main()
{ // Initializing the Linked List
Node* head = new Node(1);
head->next = new Node(2);
head->next->next = new Node(3);
head->next->next->next = new Node(4);
head->next->next->next->next = head->next;
// Function call
if (checkBipartiteList(head))
cout << "Possible\n" ;
else
cout << "Not Possible\n" ;
return 0;
} |
class ListNode {
int data;
ListNode next;
ListNode( int val) {
data = val;
next = null ;
}
} public class BipartiteLinkedList {
// Returns node inside cycle if there is a loop in the linked list, else returns null
public static ListNode detectLoop(ListNode head) {
// Floyd's Algorithm
ListNode slow = head, fast = head;
do {
slow = slow.next;
fast = fast.next != null ? fast.next.next : null ;
} while (fast != null && fast.next != null && slow != fast);
if (fast == null || fast.next == null )
return null ;
return slow;
}
// Function to check whether the list is bipartite or not
public static boolean checkBipartiteList(ListNode head) {
ListNode currNode = detectLoop(head);
// If there is no loop, then currNode will contain null
if (currNode == null )
return true ;
// If there is a loop, then currNode will contain a node inside the cycle
ListNode temp = currNode;
// Variable to store the length of the cycle
int count = 0 ;
do {
temp = temp.next;
count += 1 ;
} while (temp != currNode);
return count % 2 == 0 ;
}
// Driver program to test the above function
public static void main(String[] args) {
// Initializing the Linked List
ListNode head = new ListNode( 1 );
head.next = new ListNode( 2 );
head.next.next = new ListNode( 3 );
head.next.next.next = new ListNode( 4 );
head.next.next.next.next = head.next;
// Function call
if (checkBipartiteList(head))
System.out.println( "Possible" );
else
System.out.println( "Not Possible" );
}
} |
# Python code for the above approach # Link list node class Node:
def __init__( self , val):
self .data = val
self . next = None
# Returns Node inside cycle if there is a # loop in linked list else returns None def detectLoop(head):
# Floyd's Algorithm
slow = head
fast = head
while fast and fast. next :
slow = slow. next
fast = fast. next . next
if slow = = fast:
break
if not fast or not fast. next :
return None
return slow
# Function which checks whether the list is # bipartite or not def checkBipartiteList(head):
curr_node = detectLoop(head)
# If there is no loop, then current
# will contain None
if not curr_node:
return True
# If there is a loop, then current will
# contain a node which is inside the cycle
temp = curr_node
# Variable to store the length of the cycle
cnt = 0
while True :
temp = temp. next
cnt + = 1
if temp = = curr_node:
break
return cnt % 2 = = 0
# Driver program to test the above function # Initializing the Linked List head = Node( 1 )
head. next = Node( 2 )
head. next . next = Node( 3 )
head. next . next . next = Node( 4 )
head. next . next . next . next = head. next
# Function call if checkBipartiteList(head):
print ( "Possible" )
else :
print ( "Not Possible" )
|
// C# code for the above approach: using System;
public class ListNode {
public int data;
public ListNode next;
public ListNode( int val)
{
data = val;
next = null ;
}
} public class BipartiteLinkedList {
// Returns node inside cycle if there is a
// loop in the linked list, else returns null
public static ListNode DetectLoop(ListNode head)
{
// Floyd's Algorithm
ListNode slow = head, fast = head;
do {
slow = slow.next;
fast
= fast.next != null ? fast.next.next : null ;
} while (fast != null && fast.next != null
&& slow != fast);
if (fast == null || fast.next == null )
return null ;
return slow;
}
// Function to check whether the list is bipartite or
// not
public static bool CheckBipartiteList(ListNode head)
{
ListNode currNode = DetectLoop(head);
// If there is no loop, then currNode will contain
// null
if (currNode == null )
return true ;
// If there is a loop, then currNode will
// contain a node inside the cycle
ListNode temp = currNode;
// Variable to store the length of the cycle
int count = 0;
do {
temp = temp.next;
count += 1;
} while (temp != currNode);
return count % 2 == 0;
}
// Driver program to test the above function
public static void Main( string [] args)
{
// Initializing the Linked List
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(3);
head.next.next.next = new ListNode(4);
head.next.next.next.next = head.next;
// Function call
if (CheckBipartiteList(head))
Console.WriteLine( "Possible" );
else
Console.WriteLine( "Not Possible" );
}
} |
// JavaScript Implementation of the code // Linked list node class Node { constructor(val) {
this .data = val;
this .next = null ;
}
} // Returns the node inside a cycle if // there is a loop in the linked list; // otherwise, returns null function detectLoop(head) {
// Floyd's Algorithm
let slow = head;
let fast = head;
do {
slow = slow.next;
fast = fast.next ? fast.next.next : null ;
} while (fast && fast.next && slow !== fast);
if (!fast || !fast.next) {
return null ;
}
return slow;
} // Function that checks whether the // list is bipartite or not function checkBipartiteList(head) {
const currNode = detectLoop(head);
// If there is no loop, then
// current will contain null
if (!currNode) {
return true ;
}
// If there is a loop, then current
// will contain a node which is
// inside the cycle
let temp = currNode;
// Variable to store the length
// of the cycle
let cnt = 0;
do {
temp = temp.next;
cnt += 1;
} while (temp !== currNode);
return cnt % 2 === 0;
} // Driver program to test the above function // Initializing the Linked List const head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(4);
head.next.next.next.next = head.next; // Function call if (checkBipartiteList(head)) {
console.log( "Possible" );
} else {
console.log( "Not Possible" );
} |
Not Possible
Time Complexity: O(N), where N is the number of nodes in the Linked List
Auxiliary Space: O(1)