Leetcode Daily Question 08/09/2024 - 725. Split Linked List in Parts
Problem Description:
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.
Solution:
class ListNode:
def __init__(self, val = 0, next = None):
self.val = val
self.next = next
from typing import Optional
class Solution:
def splitListToParts(self, head: Optional[ListNode], k: int) -> List[Optional[ListNode]]:
length = 0
current = head
while current:
length += 1
current = current.next
each_length = length // k
remainder = length % k
result = [None] * k
current = head
prev = None
for i in range(k):
result[i] = current
part_length = each_length + (1 if remainder > 0 else 0)
for _ in range(part_length):
prev = current
current = current.next
if prev:
prev.next = None
remainder -= 1
return result
Explanation:
We want to split the linked list into k linked list as evenly as possible.
To do this, we first determine the length each part should have. We calculate the length of the whole linked list.
Then each part should have length of at least total length divided by k. Then we can distribute the remainder later when iterating through the linked list.
current = head
length = 0
while current:
length += 1
current = current.next
each_length = length // k
remainder = length % k
Our strategy to split the linked list is this.
Current will traverse the entirety of the original linked list to signify where the head of each linked list should be and prev will follow to terminate the individual linked lists.
We first initiate the result list with null nodes. This catches the cases where the total length is less than k. This also deals with the case where the original linked list is null.
result = [None] * k
prev = None
current = head
for i in range(k):
result[i] = current # Current is the head of each individual linked list.
part_length = each_length + (1 if remainder > 0 else 0) # Distribute the remainder.
for _ in range(part_length):
prev = current
current = current.next
if prev:
prev.next = None # Terminates the individual linked list.
remainder -= 1 # Decrement the remainder as we distribute it.
return result
The time complexity is O(n) as we need to traverse the entire linked list twice.
The space complexity is O(n) as we need to store the head of each linked list.
The full solution can be found near the top of the page.