Given the head
of a singly linked list and an integer k
, split the linked list into k
consecutive linked list parts.
The length of each part should be as equal as possible: no two parts should have a size differing by more than one. This may lead to some parts being null.
The parts should be in the order of occurrence in the input list, and parts occurring earlier should always have a size greater than or equal to parts occurring later.
Return an array of the k
parts.
Example 1:
Input: head = [1,2,3], k = 5 Output: [[1],[2],[3],[],[]] Explanation: The first element output[0] has output[0].val = 1, output[0].next = null. The last element output[4] is null, but its string representation as a ListNode is [].
Example 2:
Input: head = [1,2,3,4,5,6,7,8,9,10], k = 3 Output: [[1,2,3,4],[5,6,7],[8,9,10]] Explanation: The input has been split into consecutive parts with size difference at most 1, and earlier parts are a larger size than the later parts.
Constraints:
[0, 1000]
.0 <= Node.val <= 1000
1 <= k <= 50
This problem involves splitting a singly linked list into k
parts with lengths as equal as possible. The solution employs a straightforward approach that leverages integer division and the modulo operator to efficiently determine the size of each sublist.
Algorithm:
Determine List Length: First, traverse the linked list to determine its total number of nodes (n
).
Calculate Sublist Sizes: Calculate the average sublist length (cnt
) using integer division (n / k
) and the remainder (mod
) using the modulo operator (n % k
). cnt
represents the minimum length of each sublist, and mod
indicates how many sublists will be one element longer than cnt
.
Split the List: Iterate k
times. In each iteration:
cur
) as the head of the current sublist.m
) as cnt
plus 1 if the current iteration is less than mod
(meaning this sublist gets an extra node).m - 1
nodes to find the end of the current sublist.next
pointer of the last node of the current sublist to null
to separate it from the rest of the list.cur
to the node after the last node of the current sublist to start the next sublist.Return Sublists: Return an array of the k
sublists (potentially including empty sublists if k
is larger than the list length).
Time Complexity: O(n), where n is the number of nodes in the linked list. We traverse the list once to find its length and again to split it into sublists.
Space Complexity: O(k), where k is the number of parts. The space is used to store the array of sublist heads.
Code Implementation (Python):
# 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: Optional[ListNode], k: int) -> List[Optional[ListNode]]:
n = 0
cur = head
while cur:
n += 1
cur = cur.next
cnt, mod = divmod(n, k)
ans = [None] * k
cur = head
for i in range(k):
if cur is None:
break
ans[i] = cur
m = cnt + int(i < mod)
for _ in range(1, m):
cur = cur.next
nxt = cur.next
cur.next = None
cur = nxt
return ans
The code in other languages (Java, C++, Go, TypeScript) follows a very similar structure, adapting the syntax and data structures accordingly. The core logic remains consistent across all implementations.