# Definition for singly-linked list.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def splitListToParts(self, head: ListNode, k: int):
# Step 1: Find the total length
length = 0
curr = head
while curr:
length += 1
curr = curr.next
# Step 2: Determine the size of each part
part_size = length // k
extra = length % k
# Step 3: Split the list
res = []
curr = head
for i in range(k):
part_head = curr
size = part_size + (1 if i < extra else 0)
for j in range(size - 1):
if curr:
curr = curr.next
if curr:
next_part = curr.next
curr.next = None
curr = next_part
res.append(part_head)
return res
// Definition for singly-linked list.
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(nullptr) {}
};
class Solution {
public:
vector<ListNode*> splitListToParts(ListNode* head, int k) {
int length = 0;
ListNode* curr = head;
while (curr) {
length++;
curr = curr->next;
}
int part_size = length / k;
int extra = length % k;
vector<ListNode*> res;
curr = head;
for (int i = 0; i < k; ++i) {
ListNode* part_head = curr;
int size = part_size + (i < extra ? 1 : 0);
for (int j = 0; j < size - 1; ++j) {
if (curr) curr = curr->next;
}
if (curr) {
ListNode* next_part = curr->next;
curr->next = nullptr;
curr = next_part;
}
res.push_back(part_head);
}
return res;
}
};
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode[] splitListToParts(ListNode head, int k) {
int length = 0;
ListNode curr = head;
while (curr != null) {
length++;
curr = curr.next;
}
int part_size = length / k;
int extra = length % k;
ListNode[] res = new ListNode[k];
curr = head;
for (int i = 0; i < k; ++i) {
ListNode part_head = curr;
int size = part_size + (i < extra ? 1 : 0);
for (int j = 0; j < size - 1; ++j) {
if (curr != null) curr = curr.next;
}
if (curr != null) {
ListNode next_part = curr.next;
curr.next = null;
curr = next_part;
}
res[i] = part_head;
}
return res;
}
}
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode[]}
*/
var splitListToParts = function(head, k) {
// Step 1: Find total length
let length = 0, curr = head;
while (curr) {
length++;
curr = curr.next;
}
// Step 2: Determine size of each part
let part_size = Math.floor(length / k);
let extra = length % k;
// Step 3: Split the list
let res = [];
curr = head;
for (let i = 0; i < k; ++i) {
let part_head = curr;
let size = part_size + (i < extra ? 1 : 0);
for (let j = 0; j < size - 1; ++j) {
if (curr) curr = curr.next;
}
if (curr) {
let next_part = curr.next;
curr.next = null;
curr = next_part;
}
res.push(part_head);
}
return res;
};
You are given the head of a singly linked list, head
, and an integer k
. Your task is to split the linked list into k
consecutive parts as evenly as possible. If the number of nodes in the list is not divisible by k
, then the first few parts should have an extra node.
k
nodes, then some parts will be null
.
k
linked list heads, each representing a part.
To solve this problem, we first need to determine how to split the linked list into k
parts as evenly as possible. The main challenge is to ensure that the first few parts are longer if the list size is not perfectly divisible by k
. We also need to ensure that we do not reuse or skip any nodes.
A brute-force approach might involve repeatedly traversing the list for each part, but this would be inefficient. Instead, we can make a single pass to count the total number of nodes, then calculate the ideal size for each part. With this information, we can split the list in a single pass, carefully managing pointers to avoid node reuse.
The key insight is to calculate the base size for each part and distribute any extra nodes to the earlier parts. This ensures the most even distribution possible.
length
.
length // k
nodes. The first length % k
parts will have one extra node each.
part_size + 1
nodes if this part is one of the first extra
parts, otherwise part_size
nodes.k
parts.k
, some parts will be null
.
This approach ensures each node appears in exactly one part, and the parts are as equal as possible in size.
Example: Let the input linked list be 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10
, and k = 3
.
3 + 1
extra)1 -> 2 -> 3 -> 4
5 -> 6 -> 7
8 -> 9 -> 10
The resulting array contains the heads of three linked lists as described above.
The key to splitting a linked list into k
parts as evenly as possible is to first count the nodes, then distribute them so the first few parts get any extras. This ensures a fair split and respects the order of nodes. The solution is efficient, requiring only two passes and O(k) extra space for the result, making it both elegant and practical for large lists.