Problem
Given a linked list of N nodes where nodes can contain values 0s, 1s, and 2s only. The task is to segregate 0s, 1s, and 2s linked list such that all zeros segregate to head side, 2s at the end of the linked list, and 1s in the mid of 0s and 2s. (link)
Example 1:
Input:
N = 8
value[] = {1,2,2,1,2,0,2,2}
Output: 0 1 1 2 2 2 2 2
Explanation: All the 0s are segregated
to the left end of the linked list,
2s to the right end of the list, and
1s in between.
Example 2:
Input:
N = 4
value[] = {2,2,0,1}
Output: 0 1 2 2
Explanation: After arranging all the
0s,1s and 2s in the given format,
the output will be 0 1 2 2.
Solution
Brute Force Approach
Counting the Occurrences:
As you traverse the linked list, maintain three counters: one for the number of 0’s, one for the number of 1’s, and one for the number of 2’s.
Increment the appropriate counter based on the value of each node.
Overwriting the Data:
After counting, iterate through the linked list again.
Overwrite the data in the nodes using the counters:
Fill the first
count0
nodes with value 0.Fill the next
count1
nodes with value 1.Fill the remaining nodes with value 2.
Time - O(n)
Space - O(1)
class Solution {
static Node segregate(Node head) {
if(head==null || head.next==null) return head;
int count0 = 0;
int count1 = 0;
int count2 = 0;
Node temp = head;
while(temp!=null){
if(temp.data == 0) count0+=1;
else if(temp.data == 1) count1+=1;
else count2+=1;
temp = temp.next;
}
temp = head;
while(temp!=null){
if(count0!=0){
temp.data = 0;
count0-=1;
}
else if (count1!=0){
temp.data = 1;
count1-=1;
}
else{
temp.data = 2;
count2-=1;
}
temp = temp.next;
}
return head;
}
}
Optimal Approach
Initialization:
Create three dummy nodes (heads) for the three categories: zeros, ones, and twos.
Initialize three tail pointers (temp0, temp1, and temp2) to point to the dummy nodes.
Iterating Through the Linked List:
Traverse the original linked list.
Depending on the value of each node encountered (0, 1, or 2), append it to the corresponding category (zeros, ones, or twos).
Combining the Linked Lists:
After the traversal, combine the three linked lists:
If the ones list is not empty, attach the twos list to the end of the zeros list.
Directly attach the twos list to the ones list.
Ensure that the tail of the twos list points to null.
Return the Sorted Linked List:
- Return the next node after the dummy node for zeros.
Ways of Combining
Combining from First:
temp0.next = (ones.next!=null) ? ones.next : twos.next;
temp1.next = twos.next;
temp2.next = null;
Second way:
Combining from Last:
Start by ensuring that the tail of the twos list points to null (since it’s the end of the sorted list).
Then, combine the twos list with the ones list.
Finally, combine the ones list with the zeros list.
temp2.next = null;
temp1.next = twos.next;
temp0.next = ones.next;
Code
Time - O(n)
Space - O(1)
class Solution {
static Node segregate(Node head) {
if(head==null || head.next==null) return head;
Node zeros = new Node(0);
Node ones = new Node(0);
Node twos = new Node(0);
Node temp = head;
Node temp0 = zeros;
Node temp1 = ones;
Node temp2 = twos;
while(temp!=null){
if(temp.data == 0){
temp0.next = temp;
temp0 = temp;
}
else if(temp.data == 1){
temp1.next = temp;
temp1 = temp;
}
else{
temp2.next =temp;
temp2 = temp;
}
temp = temp.next;
}
temp2.next = null;
temp1.next = twos.next;
temp0.next = ones.next;
return zeros.next;
}
}