725. Split Linked List in Parts

WHAT TO KNOW - Sep 8 - - Dev Community

<!DOCTYPE html>





Splitting a Linked List into Parts

<br> body {<br> font-family: Arial, sans-serif;<br> line-height: 1.6;<br> margin: 0;<br> padding: 0;<br> }</p> <div class="highlight"><pre class="highlight plaintext"><code> h1, h2, h3 { color: #333; } code { background-color: #f0f0f0; padding: 2px 5px; font-family: monospace; } pre { background-color: #eee; padding: 10px; overflow-x: auto; border-radius: 5px; } img { max-width: 100%; display: block; margin: 10px auto; } .container { max-width: 800px; margin: 20px auto; padding: 20px; } .section { margin-bottom: 30px; } .example-container { margin: 20px 0; border: 1px solid #ddd; padding: 10px; } .example-title { margin-bottom: 5px; font-weight: bold; } .example-code { margin-top: 5px; } </code></pre></div> <p>




Splitting a Linked List into Parts




Introduction



Splitting a linked list into parts is a fundamental operation in data structures and algorithms. This technique involves dividing a single linked list into multiple smaller lists, often with equal or specified lengths. It finds applications in various scenarios, such as:



  • Distributed processing:
    Splitting a large dataset stored in a linked list into smaller chunks for parallel processing on multiple nodes.

  • Load balancing:
    Dividing data evenly across multiple servers or threads to improve performance.

  • Data partitioning:
    Organizing data into manageable units for efficient storage and retrieval.

  • Algorithmic problem-solving:
    Breaking down a problem into smaller subproblems that can be solved individually and then combined.


In this article, we'll explore different strategies for splitting linked lists into parts, understand the complexity involved, and provide code examples in Python for demonstration.





Basic Concepts



Before delving into the splitting techniques, let's review the essential concepts related to linked lists:



  • Linked List:
    A linear data structure where each element (node) contains data and a reference (pointer) to the next node in the sequence. Linked lists are dynamic, allowing for efficient insertion and deletion of nodes.

  • Head:
    The first node in the linked list.

  • Tail:
    The last node in the linked list.

  • Node:
    A single element in the linked list, typically containing data and a pointer to the next node.

Linked List Diagram


In our examples, we'll use a simple Python class to represent a linked list node:



class Node:
def init(self, data):
self.data = data
self.next = None




Splitting Techniques



1. Splitting into Equal Parts



This technique divides the linked list into a specified number of parts with approximately equal lengths.



Algorithm


  1. Calculate the length of the linked list.
  2. Determine the size of each part (length / number of parts).
  3. Iterate through the linked list, creating new linked lists for each part.
  4. For each part, traverse the original list for the calculated size and create new nodes for the new list.
  5. Update the tail of each new list and the head of the next part.


Python Implementation



def split_linked_list_equal_parts(head, parts):
if head is None or parts <= 0:
return []
length = 0
current = head
while current:
    length += 1
    current = current.next

part_size = length // parts
remaining = length % parts

result = []
current = head
tail = None

for i in range(parts):
    new_head = current
    count = part_size
    if i &lt; remaining:
        count += 1
    for j in range(count):
        if j == count - 1:
            tail = current
        if current.next:
            current = current.next
        else:
            break

    if tail:
        tail.next = None
    result.append(new_head)

return result

    </code></pre>
<h4>
 Example
</h4>
<div class="example-container">
 <div class="example-title">
  Example: Splitting a linked list into 3 parts
 </div>
 <div class="example-code">
  <code>
   # Example linked list: 1 -&gt; 2 -&gt; 3 -&gt; 4 -&gt; 5 -&gt; 6 -&gt; 7 -&gt; 8 -&gt; 9 

head = Node(1)
head.next = Node(2)
head.next.next = Node(3)
head.next.next.next = Node(4)
head.next.next.next.next = Node(5)
head.next.next.next.next.next = Node(6)
head.next.next.next.next.next.next = Node(7)
head.next.next.next.next.next.next.next = Node(8)
head.next.next.next.next.next.next.next.next = Node(9)

parts = 3
split_lists = split_linked_list_equal_parts(head, parts)

Print the split linked lists

for i, part in enumerate(split_lists):
print(f"Part {i + 1}: ", end="")
current = part
while current:
print(current.data, end=" -> ")
current = current.next
print("None")




Output:



Part 1: 1 -> 2 -> 3 -> None
Part 2: 4 -> 5 -> 6 -> None
Part 3: 7 -> 8 -> 9 -> None





2. Splitting into Parts with Specified Lengths



This approach allows you to specify the desired length for each part, which might not be equal.



Algorithm


  1. Create a list to store the specified lengths of each part.
  2. Iterate through the list of lengths and the original linked list.
  3. For each length, traverse the original linked list and create new nodes for the corresponding part.
  4. Update the tail of each part and the head of the next part.


Python Implementation



def split_linked_list_specified_lengths(head, lengths):
if head is None or len(lengths) == 0:
return []
result = []
current = head
tail = None

for length in lengths:
    new_head = current
    for i in range(length):
        if i == length - 1:
            tail = current
        if current.next:
            current = current.next
        else:
            break

    if tail:
        tail.next = None
    result.append(new_head)

return result

    </code></pre>
<h4>
 Example
</h4>
<div class="example-container">
 <div class="example-title">
  Example: Splitting a linked list into parts with lengths 2, 3, and 4
 </div>
 <div class="example-code">
  <code>
   # Example linked list: 1 -&gt; 2 -&gt; 3 -&gt; 4 -&gt; 5 -&gt; 6 -&gt; 7 -&gt; 8 -&gt; 9 

head = Node(1)
head.next = Node(2)
head.next.next = Node(3)
head.next.next.next = Node(4)
head.next.next.next.next = Node(5)
head.next.next.next.next.next = Node(6)
head.next.next.next.next.next.next = Node(7)
head.next.next.next.next.next.next.next = Node(8)
head.next.next.next.next.next.next.next.next = Node(9)

lengths = [2, 3, 4]
split_lists = split_linked_list_specified_lengths(head, lengths)

Print the split linked lists

for i, part in enumerate(split_lists):
print(f"Part {i + 1}: ", end="")
current = part
while current:
print(current.data, end=" -> ")
current = current.next
print("None")




Output:



Part 1: 1 -> 2 -> None
Part 2: 3 -> 4 -> 5 -> None
Part 3: 6 -> 7 -> 8 -> 9 -> None





3. Splitting into Parts with a Maximum Size



This approach divides the linked list into parts, ensuring that no part exceeds a specified maximum size.



Algorithm


  1. Iterate through the original linked list.
  2. Create a new linked list for each part.
  3. Add nodes to the new list until the maximum size is reached.
  4. Update the tail of the current part and the head of the next part.


Python Implementation



def split_linked_list_max_size(head, max_size):
if head is None or max_size <= 0:
return []
result = []
current = head
tail = None
count = 0

while current:
    new_head = current
    for i in range(max_size):
        if i == max_size - 1:
            tail = current
        if current.next:
            current = current.next
            count += 1
        else:
            break

    if tail:
        tail.next = None
    result.append(new_head)

return result

    </code></pre>
<h4>
 Example
</h4>
<div class="example-container">
 <div class="example-title">
  Example: Splitting a linked list with a maximum part size of 3
 </div>
 <div class="example-code">
  <code>
   # Example linked list: 1 -&gt; 2 -&gt; 3 -&gt; 4 -&gt; 5 -&gt; 6 -&gt; 7 -&gt; 8 -&gt; 9 

head = Node(1)
head.next = Node(2)
head.next.next = Node(3)
head.next.next.next = Node(4)
head.next.next.next.next = Node(5)
head.next.next.next.next.next = Node(6)
head.next.next.next.next.next.next = Node(7)
head.next.next.next.next.next.next.next = Node(8)
head.next.next.next.next.next.next.next.next = Node(9)

max_size = 3
split_lists = split_linked_list_max_size(head, max_size)

Print the split linked lists

for i, part in enumerate(split_lists):

print(f"Part {i + 1}: ", end="")

current = part

while current:

print(current.data, end=" -> ")

current = current.next

print("None")







Output:





Part 1: 1 -> 2 -> 3 -> None

Part 2: 4 -> 5 -> 6 -> None

Part 3: 7 -> 8 -> 9 -> None












Time and Space Complexity





The time complexity of splitting a linked list into parts depends on the chosen technique and the size of the list. In most cases, the time complexity is O(n), where n is the number of nodes in the linked list, because we need to traverse the entire list at least once.





The space complexity depends on the number of parts created. If we create a separate linked list for each part, the space complexity is O(k), where k is the number of parts. However, if we modify the original linked list in place (for example, by updating pointers), the space complexity can be O(1).










Conclusion





Splitting a linked list into parts is a common operation with various applications in data manipulation and algorithm design. We explored different techniques, including splitting into equal parts, specified lengths, and a maximum size, along with their implementations and complexities. Understanding these approaches empowers you to efficiently divide and manage linked list data in your programs.





Remember to consider the specific requirements of your application and choose the most suitable splitting technique for optimal performance.








. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player