3217. Delete Nodes From Linked List Present in Array

WHAT TO KNOW - Sep 8 - - Dev Community

<!DOCTYPE html>



Deleting Nodes From a Linked List Based on an Array

<br> body {<br> font-family: Arial, sans-serif;<br> }</p> <p>h1, h2, h3 {<br> text-align: center;<br> }</p> <p>img {<br> display: block;<br> margin: 0 auto;<br> }</p> <p>code {<br> background-color: #f2f2f2;<br> padding: 5px;<br> border-radius: 5px;<br> font-family: monospace;<br> }<br>



Deleting Nodes From a Linked List Based on an Array



Introduction



In the realm of data structures, linked lists and arrays are fundamental building blocks, each possessing unique strengths and weaknesses. Linked lists offer dynamic memory allocation, making them ideal for situations where the size of the data is unknown beforehand, while arrays provide efficient random access. This article explores a fascinating problem: deleting nodes from a linked list based on an array of values.



Imagine you have a linked list representing a collection of items. You are also given an array containing the values of the nodes you want to remove from the linked list. This problem arises in various scenarios, such as data filtering, duplicate removal, or managing specific subsets of information.



Main Concepts



To effectively tackle this challenge, we need to understand the core concepts involved:


  1. Linked Lists

A linked list is a linear data structure where elements are linked together using pointers. Each node in the list contains data and a pointer (or link) to the next node. Linked lists offer several advantages:

  • Dynamic memory allocation: Linked lists can grow or shrink dynamically as needed, unlike arrays which have a fixed size.
  • Efficient insertion and deletion: Adding or removing nodes in a linked list is relatively straightforward, especially compared to arrays where shifting elements can be time-consuming. Singly Linked List

    The above image shows a simple linked list representation where each node contains data and a pointer to the next node.

    1. Arrays

    Arrays are linear data structures that store a fixed-size collection of elements of the same data type in contiguous memory locations. Their key features include:

  • Random access: Elements in an array can be accessed directly using their index, enabling efficient retrieval.
  • Fixed size: Arrays have a predetermined size during initialization, and resizing can be expensive.

    1. Problem Statement

    The problem statement is as follows: Given a linked list and an array of values, delete all nodes from the linked list whose values are present in the array.

    Techniques and Solutions

    Let's delve into different approaches to solve this problem:

  • Naive Approach

    A straightforward approach involves iterating through the linked list and comparing each node's value with every element in the array. If a match is found, the node is deleted.

Algorithm:

  1. Iterate through the linked list: Traverse the linked list using a pointer, starting from the head.
  2. Iterate through the array: For each node in the linked list, iterate through the entire array.
  3. Check for value match: Compare the node's value with each element in the array.
  4. Delete node if match found: If a match is found, delete the node from the linked list using appropriate deletion methods.
  5. Continue traversal: Move to the next node in the linked list and repeat steps 2-4. Code (Python):
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

def delete_nodes_array(head, arr):
    temp = head
    while temp:
        for val in arr:
            if temp.data == val:
                temp.data = temp.next.data
                temp.next = temp.next.next
                break
        temp = temp.next
    return head

Time Complexity: O(m * n), where m is the number of nodes in the linked list and n is the number of elements in the array. This approach has a high time complexity because it involves nested iterations.

Space Complexity: O(1), as the algorithm only requires constant extra space.

  1. Hash Table Approach

A more efficient solution uses a hash table to store the values from the array. This technique significantly reduces the search time.

Algorithm:

  1. Create a hash table: Create a hash table to store the values from the array.
  2. Insert values into hash table: Iterate through the array and insert each element into the hash table as keys.
  3. Iterate through the linked list: Traverse the linked list using a pointer, starting from the head.
  4. Check for presence in hash table: For each node in the linked list, check if its value is present in the hash table as a key.
  5. Delete node if present: If the value exists in the hash table, delete the node from the linked list using appropriate deletion methods.
  6. Continue traversal: Move to the next node in the linked list and repeat steps 4-5. Code (Python):
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

def delete_nodes_hash(head, arr):
    hash_table = set(arr)
    temp = head
    prev = None
    while temp:
        if temp.data in hash_table:
            if prev:
                prev.next = temp.next
            else:
                head = temp.next
        else:
            prev = temp
        temp = temp.next
    return head

Time Complexity: O(m + n), where m is the number of nodes in the linked list and n is the number of elements in the array. This approach is more efficient because it reduces the search time to O(1) on average using a hash table.

Space Complexity: O(n), as the hash table requires additional space to store the array elements.

  1. Sorting Approach

If the array is already sorted, you can utilize a two-pointer technique to efficiently delete the nodes from the linked list.

Algorithm:

  1. Sort the array: Sort the array in ascending order.
  2. Initialize two pointers: Set a pointer (array_ptr) to the beginning of the array and a pointer (list_ptr) to the head of the linked list.
  3. Compare and delete: While list_ptr is not None:
    • If the value pointed to by list_ptr is equal to the value pointed to by array_ptr, delete the node pointed to by list_ptr and advance array_ptr.
    • Otherwise, move list_ptr to the next node. Code (Python):
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

def delete_nodes_sorted(head, arr):
    arr.sort()
    array_ptr = 0
    temp = head
    prev = None
    while temp:
        if array_ptr &lt; len(arr) and temp.data == arr[array_ptr]:
            if prev:
                prev.next = temp.next
            else:
                head = temp.next
            array_ptr += 1
        else:
            prev = temp
        temp = temp.next
    return head

Time Complexity: O(n log n) + O(m), where n is the number of elements in the array and m is the number of nodes in the linked list. Sorting the array takes O(n log n) time, and the remaining steps have a linear time complexity.

Space Complexity: O(1), as the algorithm modifies the original array in place.


Example


Scenario:
  • Linked List: 1 -> 2 -> 3 -> 4 -> 5
  • Array: [2, 4]

Desired Output:

  • Linked List: 1 -> 3 -> 5

Solution using the Hash Table Approach:

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

def delete_nodes_hash(head, arr):
    hash_table = set(arr)
    temp = head
    prev = None
    while temp:
        if temp.data in hash_table:
            if prev:
                prev.next = temp.next
            else:
                head = temp.next
        else:
            prev = temp
        temp = temp.next
    return head

# Create linked list
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)

# Array of values to delete
arr = [2, 4]

# Delete nodes using the hash table approach
new_head = delete_nodes_hash(head, arr)

# Print the modified linked list
temp = new_head
while temp:
    print(temp.data, end=" -&gt; ")
    temp = temp.next
print("None")

Output:

1 -&gt; 3 -&gt; 5 -&gt; None




Conclusion





This article has explored the problem of deleting nodes from a linked list based on an array. We've discussed various techniques, including a naive approach, a hash table approach, and a sorting approach. Each approach has its own trade-offs in terms of time and space complexity. The choice of the most suitable approach depends on the specific requirements of the problem, such as the size of the array and the frequency of operations.





By understanding these concepts and techniques, developers can efficiently handle the deletion of nodes from linked lists based on arrays, ensuring clean and optimized data manipulation within their applications.




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