Open In App

Check Whether a Linked List is Bipartite or Not

Last Updated : 27 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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++




// 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;
}


Java




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");
    }
}


Python3




# 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#




// 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




// 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");
}


Output

Not Possible









Time Complexity: O(N), where N is the number of nodes in the Linked List
Auxiliary Space: O(1)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads