Table of contents
1.
Introduction 
2.
Brute Force Approach
2.1.
Algorithm
2.2.
C++ code
2.3.
Algorithm Complexity
3.
Efficient Approach
3.1.
Algorithm 
3.2.
C++ code
3.3.
Algorithm Complexity
4.
Frequently Asked Questions
4.1.
What is a linked list?
4.2.
What is the key difference between a singly linked list and a doubly-linked list?
4.3.
What is the intuition behind the efficient approach discussed above?
5.
Conclusion
Last Updated: Mar 27, 2024
Hard

Partitioning a Linked List around a given Value and Keeping the Original Order

Author Riya
1 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?
Linked List

Introduction 

This article will discuss the problem “Partitioning a linked list around a given value and keeping the original order” and its solution. Before jumping into the details of the problem and approach to solve it, you need to know about the linked list data structure.

Now, let’s understand the problem. In this problem, a linked list and a value ‘x’ is given, and we have to partition the linked list such a way that all the nodes with values less than ‘x’ come first, then the nodes having values equal to ‘x’ and then, at last, the nodes with values greater than ‘x’. And, we have to do this partitioning along with preserving the original order of nodes in the three partitions.

 

Let’s understand this problem of partitioning a linked list by taking an example.

Assume the given linked list is : 1 -> 4 -> 5 -> 9 -> 8 -> 5 -> 2

and given x = 5

We can see that there are three nodes having values less than 5, which arranged in the original order are as follows:

1 -> 4 -> 2

There are two nodes having values equal to 5, which arranged in the original order are as follows:

5 -> 5

We can see that there are two nodes having values less than 5, which arranged in the original order are as follows:

9 -> 8

So, output of “partitioning a linked list” for the linked list and ‘x’ given in the example should be: 1 -> 4 -> 2 -> 5 -> 5 -> 9 -> 8

Recommended Topic, Floyds Algorithm

Brute Force Approach

In this problem “Partitioning a linked list around a given value”, we have to partition the given linked list such that all the nodes with values less than ‘x’ come first, then the nodes having values equal to ‘x’ and then, at last, the nodes with values greater than ‘x’ and also the original order in the three partitions remain same. Here ‘x’ is the given value around which partitioning of the linked list is to be done.

 

So, we can create three different linked lists for storing the nodes having values less than ‘x’, equal to ‘x’, and greater than ‘x’. The solution is to traverse the given linked list. The following three cases will arise:

  1. The value of the current node will be less than ‘x’ - In this case, add a node to the linked list, storing the nodes having values less than ‘x’.
  2. The value of the current node will be equal to the ‘x’ - In this case, add a node to the linked list, storing the nodes having values equal to ‘x’.
  3. The value of the current node will be greater than ‘x’ - In this case, add a node to the linked list, storing the nodes having values greater than ‘x’.

 

After traversing through all the nodes of the given linked list, concatenate the three linked lists that have been created in the following order:

First, the linked list which has stored the nodes with values less than ‘x’, then the one which has stored the nodes with values equal to ‘x’, and at last the one which has stored the nodes with values greater than ‘x’. 

                                                   

Algorithm

Step 1. Create a class ‘Node’ for creating the linked lists.

Step 2. Then create the function “partition()” for partitioning a linked list around a given value, which will take two inputs - the pointer pointing to the given linked list's head node and the given value ‘x’.

Inside the function, create six node pointers for pointing to the head node and last node of each of the three linked lists that we are creating to separate the nodes with values less than ‘x’, equal to ‘x’, and greater than ‘x’.

Step 3.  Now create a node pointer “curr_node” to point to the current node of the linked list and, starting from the head node, traverse all the nodes of the linked list using this “curr_node” pointer and a “while loop”. While traversing the linked list, if the current node's value is less than ‘x’, create a new node with the same value as the current node and add it to the linked list storing the nodes with values less than ‘x’. Similarly, if the current node's value is equal to or greater than ‘x’, create new nodes and add them to the respective linked list. 

Step 4. When “curr_node” becomes “NULL", i.e., after traversing all the nodes, concatenate the three linked lists using their head and last node pointers in the required order as explained in the above “efficient approach” section.

Step 5. Finally, after concatenating the linked list, return its head.
 

C++ code

#include <bits/stdc++.h>
using namespace std;

// Class for creating nodes of the linked list
class Node {
       public:
            int data;
            Node* next;
            Node(int val) {
                   this->data = val;
                   this->next = NULL;
            }
};

// Function to print the linked list
void printList(Node* head)
  {
       Node* curr_node = head;
       while(curr_node != NULL)
           {
                   if(curr_node->next == NULL)  {
                          cout<< curr_node->data <<" ";
                   }
                   else {
                          cout<<curr_node->data<<" -> ";
                   }
                   curr_node = curr_node->next;
           }
           cout<<endl;
  }

// Function for partitioning a linked list around a given value 
Node* partition(Node* head, int x)
  {
           // Head node of the linked list for storing nodes with values less than x
           Node* less = NULL;

           // Last node of the linked list for storing nodes with values less than x
           Node* less_last = NULL;
  
           // Head node of the linked list for storing nodes with values equal to x
           Node* equal = NULL;

            // Last node of the linked list for storing nodes with values equal to x
            Node* equal_last = NULL;
  
            // Head node of the linked list for storing nodes with values greater than x
            Node* greater = NULL;

            // Last node of the linked list for storing nodes with values greater than x
            Node* greater_last = NULL;
  
            Node* curr_node = head;
            while(curr_node != NULL)
              {
                   if(curr_node->data < x)
                       {
                           if(less == NULL)
                                {
                                     less = new Node(curr_node->data);
                                     less_last = less;
                                 }
                                 else  {
                                     less_last->next = new Node(curr_node->data);
                                     less_last = less_last->next;
                                  }
                       }
                   else if(curr_node->data == x)
                       {
                                if(equal == NULL)
                                   {
                                         equal = new Node(curr_node->data);
                                         equal_last = equal;
                                   }
                                else {
                                         equal_last->next = new Node(curr_node->data);
                                          equal_last = equal_last->next;
                                 }
                       }
                   else {
                                if(greater == NULL)
                                     {
                                           greater = new Node(curr_node->data);
                                           greater_last = greater;
                                     }
                                 else {
                                            greater_last->next = new Node(curr_node->data);
                                             greater_last = greater_last->next;
                                  }
                    }
                    curr_node = curr_node->next;
     }
     
       
   // Concatenate the three lists in order      
   // If list with less value nodes is empty
    if (less == NULL)
    {
        if (equal == NULL)
            return greater;
        equal_last->next = greater;
        return equal;
    }
 
    /*
       If the list with less value nodes is not empty
       and list with equal value nodes is empty
    */
    if (equal == NULL)
    {
        less_last->next = greater;
        return less;
    }
 
    // If both lists with less and equal values are non-empty
    less_last->next = equal;
    equal_last->next = greater;
    return  less;
  }

int main()
{
     Node* head = new Node(1);
     head->next = new Node(4);
     head->next->next = new Node(5);
     head->next->next->next = new Node(9);
     head->next->next->next->next = new Node(8);
     head->next->next->next->next->next = new Node(5);
     head->next->next->next->next->next->next = new Node(2);

     cout<<"The given linked list is: "<<endl;
     printList(head);

     int x =5;

     // Call the function for partitioning a linked list around a given value
     head = partition(head, x);

     cout<<"The linked list after partition is: "<<endl;
     printList(head);
}
You can also try this code with Online C++ Compiler
Run Code

 

Output:

 

The given linked list is: 
1 -> 4 -> 5 -> 9 -> 8 -> 5 -> 2 
The linked list after partition is: 
1 -> 4 -> 2 -> 5 -> 5 -> 9 -> 8 Algorithm Complexity: 
You can also try this code with Online C++ Compiler
Run Code

Algorithm Complexity

Time Complexity: O(N)

In the function “partition()” created for partitioning a linked list, we have created a “while loop” to one by one traverse all the nodes of the given linked list. So, the time complexity is O(N), where ‘N’ is the number of nodes in the given linked list.

 

Space Complexity: O(N) 

 In the function “partition()” created for partitioning a linked list, We have created new linked lists for storing the nodes separately according to their value with respect to ‘x’. The total number of new nodes created is ‘N’, where ‘N’ is the number of nodes in the given linked list. So, the space complexity is O(N).

Efficient Approach

In the brute force approach discussed above, we are creating new nodes. So, the space complexity is O(N). We can improve the space complexity by using the nodes of the original linked list instead of creating new nodes.

In this approach of partitioning a linked list around a given value, we will create three different linked lists and traverse all the nodes of the given linked list in a similar manner as in the brute force approach, and again three different cases will arise:

  1. The value of the current node will be less than ‘x’  - In this case, we will append the current node to the linked list storing the nodes with values less than ‘x’.
  2. The value of the current node will be equal to the ‘x’ - In this case, we will append the current node to the linked list that is storing the nodes with values equal to ‘x’
  3. The value of the current node will be greater than ‘x’ - In this case, we will append the current node to the linked list storing the nodes with values greater than ‘x’.

After traversing all the nodes of the linked list and appending them to the new linked lists according to their values with respect to ‘x’, we will concatenate the three linked lists in the following order:

First, the linked list which has stored the nodes with values less than ‘x’, then the one which has stored the nodes with values equal to ‘x’, and at last the one which has stored the nodes with values greater than ‘x’.   

                                                                                          

Algorithm 

Step 1. Create a class ‘Node’ for creating the linked lists.

Step 2. Then create the function “partition()” for partitioning a linked list around a given value, which will take two inputs - the pointer pointing to the given linked list's head node and the given value ‘x’.

Inside the function, create six node pointers for pointing to the head node and last node of each of the three linked lists to separate the nodes with values less than ‘x’, equal to ‘x’, and greater than ‘x’.

Step 3.  Now create two node pointers, “curr_node” and “next_node”, to point to the current node of the linked list and the next node of the current node, respectively. Starting from the head node, traverse all the nodes of the linked list using this “curr_node” pointer and a “while loop”. While traversing the linked list, first store the next node of the current node in the pointer “next_node”, and then if the value of a current node is less than ‘x’, append the current node to the linked list, which is storing the nodes with values less than ‘x’ and make its next node equal to “NULL”. Similarly, if the current node's value is equal to or greater than ‘x’, append the current node and to the respective linked list. And after processing the current node, go to the next node using the “next_node” pointer in which we have already stored its next node.

Step 4. When “curr_node” becomes “NULL”, i.e., after traversing all the nodes, concatenate the three linked lists using their head and last node pointers in the required order as explained in the above “efficient approach” section.

Step 5. Finally, after concatenating the linked list, return its head.

 

C++ code

#include <bits/stdc++.h>
using namespace std;

// Class for creating nodes of the linked list
class Node {
public:
int data;
Node* next;
Node(int val) {
this->data = val;
this->next = NULL;
                 }
};

// Function to print the linked list
void printList(Node* head)
  {
   Node* curr_node = head;
   while(curr_node != NULL)
     {
      if(curr_node->next == NULL) {
              cout << curr_node->data << " ";
       }
      else {
              cout << curr_node->data << " -> ";
      }
      curr_node = curr_node->next;
     }
   cout<<endl;
  }

// Function for partitioning a linked list around a given value  
Node* partition(Node* head, int x)
  {

   // Head node of the linked list for storing nodes with values less than x
   Node* less = NULL;

   // Last node of the linked list for storing nodes with values less than x
   Node* less_last = NULL;
  
   // Head node of the linked list for storing nodes with values equal to x
   Node* equal = NULL;

   // Last node of the linked list for storing nodes with values equal to x
   Node* equal_last = NULL;
  
   // Head node of the linked list for storing nodes with values greater than x
   Node* greater = NULL;

   // Last node of the linked list for storing nodes with values greater than x
   Node* greater_last = NULL;
  
   Node* curr_node = head;
   Node* next_node;
  
   while(curr_node != NULL)
     {
      next_node = curr_node->next;
      if(curr_node->data < x)
        {
         if(less == NULL)
           {
              less = curr_node;
              less_last = less;
              less_last->next = NULL;
           }
         else {
           less_last->next = curr_node;
           less_last = less_last->next;
           less_last->next = NULL;
         }
        }
      else if(curr_node->data == x)
        {
         if(equal == NULL)
           {
              equal = curr_node;
              equal_last = equal;
              equal_last->next = NULL;
           }
         else {
           equal_last->next = curr_node;
           equal_last = equal_last->next;
           equal_last->next = NULL;
         }
        }
      else {
        if(greater == NULL)
           {
              greater = curr_node;
              greater_last = greater;
              greater_last->next = NULL;
           }
         else {
           greater_last->next = curr_node;
           greater_last = greater_last->next;
           greater_last->next = NULL;
         }
      }
      curr_node = next_node;
     }
     
       
   // Concatenate the three lists in order        
   // If list with less value nodes is empty
    if (less == NULL)
    {
        if (equal == NULL)
            return greater;
        equal_last->next = greater;
        return equal;
    }
 
    /*
       If the list with less value nodes is not empty
       and list with equal value nodes is empty
    */
    if (equal == NULL)
    {
        less_last->next = greater;
        return less;
    }
 
    // If both lists with less and equal values are non-empty
    less_last->next = equal;
    equal_last->next = greater;
    return  less;
  }
int main()
{
Node* head = new Node(1);
head->next = new Node(4);
head->next->next = new Node(5);
head->next->next->next = new Node(9);
head->next->next->next->next = new Node(8);
head->next->next->next->next->next = new Node(5);
head->next->next->next->next->next->next = new Node(2);

cout<<"The given linked list is: "<<endl;
printList(head);

int x =5;

// Call the function for partitioning a linked list around a given value
head = partition(head, x);

cout<<"The linked list after partition is: "<<endl;
printList(head);
} 
You can also try this code with Online C++ Compiler
Run Code

Output:

The given linked list is: 
1 -> 4 -> 5 -> 9 -> 8 -> 5 -> 2 
The linked list after partition is: 
1 -> 4 -> 2 -> 5 -> 5 -> 9 -> 8 

Algorithm Complexity

Time Complexity: O(N)

In the function “partition()” created for partitioning a linked list,  we have created a “while loop” to one by one traverse all the nodes of the given linked list. So, the time complexity is O(N), where ‘N’ is the number of nodes in the given linked list.

 

Space Complexity: O(1) 

As we are not creating any new nodes and using constant space, the space complexity is O(1).

Must Read Difference between ArrayList and LinkedList

Frequently Asked Questions

What is a linked list?

A linked list is a linear data structure that is formed by connected nodes. Each node has a value associated with it and the pointer(s) to its directly connected node(s).   

What is the key difference between a singly linked list and a doubly-linked list?

A singly-linked list is unidirectional, which means that the node of a singly-linked list contains the pointer to its next node only. In contrast, a doubly-linked list is bidirectional, and its node contains the pointer to its next and previous nodes.

What is the intuition behind the efficient approach discussed above?

In the brute force approach, we are creating new nodes with the same value as the nodes in the given linked list for each node and then inserting those newly created nodes in the three separate linked lists according to their values. But we have to just separate the nodes according to their values, so we can use the same nodes to insert in the three separate linked lists. Thus we arrived at the efficient approach where we are using the nodes of the original linked list to reduce the space complexity.

Conclusion

This article discussed the “Partitioning a linked list around a given value and keeping the original order” problem, discussed the brute force approach and a space-efficient approach to solve the problem, and discussed the time and space complexities. If you want to practice this problem, then you can visit Coding Ninjas Studio.

Recommended Reading:

Do check out The Interview guide for Product Based Companies as well as some of the Popular Interview Problems from Top companies like Amazon, Adobe, Google, Uber, Microsoft, etc. on Coding Ninjas Studio.

Also check out some of the Guided Paths on topics such as Data Structure and Algorithms, Competitive Programming, Operating Systems, Computer Networks, DBMS, System Design, etc. as well as some Contests, Test Series, Interview Bundles, and some Interview Experiences curated by top Industry Experts only on Coding Ninjas Studio.

Cheers!

Live masterclass