Partition a Linked List into K continuous groups with difference in their sizes at most 1
Given a linked list consisting of N nodes and an integer K, the task is to split the given Linked List into K continuous groups such that the difference between the size of the adjacent groups after splitting is at most 1 and the groups are sorted in descending order of their lengths.
Note: A group with 0 elements can also be formed.
Examples:
Input: 1 ? 2 ? 3 ? 4, K = 5
Output: {{1}, {2}, {3}, {4}, {}}
Explanation: Required splits are {{1 -> NULL}, {2 -> NULL}, {3 -> NULL}, {4 -> NULL}, {NULL}}.
Input: LL: 1 ? 2 ? 3 ? 4 ? 5 ? 6 ? 7 ? 8, K = 3
Output: {{1, 2, 3}, {4, 5, 6}, {7, 8}}
Approach: The given problem can be solved based on the observation that forming first N % K groups of size (N / K + 1) and the remaining K – (N % K) groups of size N / K satisfies the conditions. Follow the steps below to solve the problem:
- Initialize a vector of the linked list, says ans, that stores the K groups.
- Store the value of N / K and N % K in the variables, say L and R.
- Traverse the given linked list and perform the following steps:
- Store the value of L in a variable say X and the value of head in the variable say currHead and last.
- If the value of R is positive, then update the value of head to head->next.
- Iterate a loop until X is non-zero and perform the following steps:
- If the last node is the same as the head node then move the head node to the next node.
- Otherwise, join the links between the last node and the head node and update the last to head, and move the head node to the next node.
- Push the current Linked List as the currentHead in the vector ans[].
- If the value of K is greater than 0, then push the NULL Linked List in ans and decrement K by 1.
- After completing the above steps, print the elements of all the Linked List stored in the vector ans[].
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct ListNode {
int val;
struct ListNode* next;
};
void push(ListNode** head_ref,
int node_val)
{
ListNode* new_node = new ListNode();
new_node->val = node_val;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
void splitListInParts(ListNode* head,
int K)
{
vector<ListNode*> ans;
if (!head) {
while (K--)
ans.push_back(NULL);
}
int N = 0;
ListNode* p = head;
while (p) {
p = p->next;
N++;
}
int len = N / K;
int rem = N % K;
p = head;
while (K > 0 && p) {
int x = len;
ListNode* curr_head = p;
ListNode* last = p;
if (rem > 0) {
p = p->next;
rem--;
}
while (x--) {
if (last == p)
p = p->next;
else {
last->next = p;
last = p;
p = p->next;
}
}
last->next = NULL;
ans.push_back(curr_head);
K--;
}
while (K > 0) {
ans.push_back(NULL);
K--;
}
cout << "{" ;
for ( int i = 0; i < ans.size(); i++) {
cout << "{" ;
while (ans[i]) {
cout << ans[i]->val << " " ;
ans[i] = ans[i]->next;
}
cout << "}" ;
if (i != ans.size() - 1)
cout << ", " ;
}
cout << "}" ;
}
int main()
{
ListNode* root = NULL;
push(&root, 8);
push(&root, 7);
push(&root, 6);
push(&root, 5);
push(&root, 4);
push(&root, 3);
push(&root, 2);
push(&root, 1);
int K = 3;
splitListInParts(root, K);
return 0;
}
|
Java
import java.util.*;
class GFG{
static class ListNode
{
int val;
ListNode next;
};
static ListNode push(ListNode head_ref,
int node_val)
{
ListNode new_node = new ListNode();
new_node.val = node_val;
new_node.next = head_ref;
head_ref = new_node;
return head_ref;
}
static void splitListInParts(ListNode head,
int K)
{
Vector<ListNode> ans = new Vector<ListNode>();
if (head == null )
{
while (K-- > 0 )
ans.add( null );
}
int N = 0 ;
ListNode p = head;
while (p.next != null )
{
p = p.next;
N++;
}
int len = N / K;
int rem = N % K;
p = head;
while (K > 0 && p.next != null )
{
int x = len;
ListNode curr_head = p;
ListNode last = p;
if (rem > 0 )
{
p = p.next;
rem--;
}
while (x-- > 0 )
{
if (last == p)
p = p.next;
else
{
last.next = p;
last = p;
p = p.next;
}
}
last.next = null ;
ans.add(curr_head);
K--;
}
while (K > 0 )
{
ans.add( null );
K--;
}
System.out.print( "{" );
for ( int i = 0 ; i < ans.size(); i++)
{
System.out.print( "{" );
while (ans.get(i) != null )
{
System.out.print(ans.get(i).val + " " );
ans.set(i, ans.get(i).next);
}
System.out.print( "}" );
if (i != ans.size() - 1 )
System.out.print( ", " );
}
System.out.print( "}" );
}
public static void main(String[] args)
{
ListNode root = new ListNode();
root = push(root, 8 );
root = push(root, 7 );
root = push(root, 6 );
root = push(root, 5 );
root = push(root, 4 );
root = push(root, 3 );
root = push(root, 2 );
root = push(root, 1 );
int K = 3 ;
splitListInParts(root, K);
}
}
|
Python3
class ListNode:
def __init__( self , key):
self .val = key
self . next = None
def push(head_ref, node_val):
new_node = ListNode(node_val)
new_node. next = head_ref
return new_node
def splitListInParts(head, K):
ans = []
if (head is None ):
while (K > 0 ):
k - = 1
ans.append( None )
N = 0
p = head
while (p is not None ):
p = p. next
N + = 1
length = int (N / K)
rem = int (N % K)
p = head
while (K > 0 and p is not None ):
x = length
curr_head = p
last = p
if (rem > 0 ):
p = p. next
rem - = 1
while (x > 0 ):
x - = 1
if (last = = p):
p = p. next
else :
last. next = p
last = p
p = p. next
last. next = None
ans.append(curr_head)
K - = 1
while (K > 0 ):
ans.append( None )
K - = 1
print ( "{" , end = "")
for i in range ( len (ans)):
print ( "{" , end = " " )
while (ans[i] is not None ):
print (ans[i].val, end = " " )
ans[i] = ans[i]. next
print ( "}" , end = "")
if (i ! = len (ans) - 1 ):
print ( ", " , end = "")
print ( "}" )
root = None
root = push(root, 8 )
root = push(root, 7 )
root = push(root, 6 )
root = push(root, 5 )
root = push(root, 4 )
root = push(root, 3 )
root = push(root, 2 )
root = push(root, 1 )
K = 3
splitListInParts(root, K)
|
C#
using System;
using System.Collections.Generic;
public class GFG{
class ListNode
{
public int val;
public ListNode next;
};
static ListNode push(ListNode head_ref,
int node_val)
{
ListNode new_node = new ListNode();
new_node.val = node_val;
new_node.next = head_ref;
head_ref = new_node;
return head_ref;
}
static void splitListInParts(ListNode head,
int K)
{
List<ListNode> ans = new List<ListNode>();
if (head == null )
{
while (K-- > 0)
ans.Add( null );
}
int N = 0;
ListNode p = head;
while (p.next != null )
{
p = p.next;
N++;
}
int len = N / K;
int rem = N % K;
p = head;
while (K > 0 && p.next != null )
{
int x = len;
ListNode curr_head = p;
ListNode last = p;
if (rem > 0)
{
p = p.next;
rem--;
}
while (x-- > 0)
{
if (last == p)
p = p.next;
else
{
last.next = p;
last = p;
p = p.next;
}
}
last.next = null ;
ans.Add(curr_head);
K--;
}
while (K > 0)
{
ans.Add( null );
K--;
}
Console.Write( "{" );
for ( int i = 0; i < ans.Count; i++)
{
Console.Write( "{" );
while (ans[i] != null )
{
Console.Write(ans[i].val + " " );
ans[i] = ans[i].next;
}
Console.Write( "}" );
if (i != ans.Count - 1)
Console.Write( ", " );
}
Console.Write( "}" );
}
public static void Main(String[] args)
{
ListNode root = new ListNode();
root = push(root, 8);
root = push(root, 7);
root = push(root, 6);
root = push(root, 5);
root = push(root, 4);
root = push(root, 3);
root = push(root, 2);
root = push(root, 1);
int K = 3;
splitListInParts(root, K);
}
}
|
Javascript
<script>
class ListNode {
constructor()
{
this .val = 0;
this .next = null ;
}
};
function pushIn(head_ref, node_val)
{
var new_node = new ListNode();
new_node.val = node_val;
new_node.next = (head_ref);
head_ref = new_node;
return head_ref;
}
function splitListInParts(head, K)
{
var ans = [];
if (!head) {
while (K--)
ans.push( null );
}
var N = 0;
var p = head;
while (p) {
p = p.next;
N++;
}
var len = parseInt(N / K);
var rem = N % K;
p = head;
while (K > 0 && p) {
var x = len;
var curr_head = p;
var last = p;
if (rem > 0) {
p = p.next;
rem--;
}
while (x--) {
if (last == p)
p = p.next;
else {
last.next = p;
last = p;
p = p.next;
}
}
last.next = null ;
ans.push(curr_head);
K--;
}
while (K > 0) {
ans.push( null );
K--;
}
document.write( "{" );
for ( var i = 0; i < ans.length; i++) {
document.write( "{" );
while (ans[i]) {
document.write( ans[i].val + " " );
ans[i] = ans[i].next;
}
document.write( "}" );
if (i != ans.length - 1)
document.write( ", " );
}
document.write( "}" );
}
var root = null ;
root = pushIn(root, 8);
root = pushIn(root, 7);
root = pushIn(root, 6);
root = pushIn(root, 5);
root = pushIn(root, 4);
root = pushIn(root, 3);
root = pushIn(root, 2);
root = pushIn(root, 1);
var K = 3;
splitListInParts(root, K);
</script>
|
Output:
{{1 2 3 }, {4 5 6 }, {7 8 }}
Time Complexity: O(N)
Auxiliary Space: O(N)
Last Updated :
25 Jan, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...