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)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!