Remove Linked List Elements

🏠 ⬅️ ➡️

Given the head of a linked list and an integer val, remove all the nodes of the linked list that has Node.val == val, and return the new head.

Example 1:

Input: head = [1,2,6,3,4,5,6], val = 6 Output: [1,2,3,4,5]

Example 2:

Input: head = [], val = 1 Output: []

Example 3:

Input: head = [7,7,7,7], val = 7 Output: []

Constraints:

  • The number of nodes in the list is in the range [0, 104].
  • 1 <= Node.val <= 50
  • 0 <= val <= 50

Note: This problem is from LeetCode.
Compiled
Executed
Correct
program main
    use :: linked_list_mod
    implicit none

    type(linked_list) :: head
    integer :: val

    ! Example 1
    call head%push(1)
    call head%push(2)
    call head%push(6)
    call head%push(3)
    call head%push(4)
    call head%push(5)
    call head%push(6)
    val = 6
    print '(A)', 'Example 1:'
    print '(A)', 'Input: head = [' // head%to_string() // '], val = ', val
    print '(A)', 'Output: head = [' // remove_nodes(head, val)%to_string() // ']'

    ! Example 2
    call head%clear()
    val = 1
    print '(A)', 'Example 2:'
    print '(A)', 'Input: head = [' // head%to_string() // '], val = ', val
    print '(A)', 'Output: head = [' // remove_nodes(head, val)%to_string() // ']'

    ! Example 3
    call head%clear()
    call head%push(7)
    call head%push(7)
    call head%push(7)
    call head%push(7)
    val = 7
    print '(A)', 'Example 3:'
    print '(A)', 'Input: head = [' // head%to_string() // '], val = ', val
    print '(A)', 'Output: head = [' // remove_nodes(head, val)%to_string() // ']'

contains

    function remove_nodes(head, val) result(new_head)
        type(linked_list), intent(inout) :: head
        integer, value :: val
        type(linked_list) :: new_head

        type(linked_list), pointer :: current => null(), next => null()

        if (associated(head)) then
            current => head
            do while (associated(current))
                next => current%next
                if (current%val == val) then
                    deallocate(current)
                else
                    allocate(new_head)
                    new_head%val = current%val
                    new_head%next => next
                    current => next
                end if
            end do
        end if
    end function remove_nodes

end program main
Compiled
Executed
Correct
module linked_list_remove
implicit none
private
public :: linked_list_remove

type linked_list
    integer :: val
    type(linked_list), pointer :: next => null()
end type linked_list

interface linked_list_remove
    module procedure remove_linked_list
end interface

contains

function remove_linked_list(head, val) result(new_head)
    type(linked_list), target, intent(in) :: head
    integer, intent(in) :: val
    type(linked_list), pointer :: current, new_head

    current => head
    new_head => head

    do while (associated(current))
        if (current%val == val) then
            if (associated(current%next)) then
                new_head => current%next
            end if
        else
            new_head%next => current
            new_head => new_head%next
        end if
        current => current%next
    end do

    nullify(new_head%next)
end function remove_linked_list
end module linked_list_remove

program test_linked_list_remove
use linked_list_remove
implicit none

type(linked_list) :: head
type(linked_list), pointer :: current
integer :: val

! Example 1
head%val = 1
head%next => null()
current => head
do while (associated(current))
    if (current%val == 2) then
        current%next => null()
        exit
    end if
    current => current%next
end do
call remove_linked_list(head, 6)
write (*,*) 'Example 1:', head%val

! Example 2
head%val = 1
head%next => null()
call remove_linked_list(head, 1)
write (*,*) 'Example 2:', head%val

! Example 3
head%val = 7
head%next => null()
call remove_linked_list(head, 7)
write (*,*) 'Example 3:', head%val

end program test_linked_list_remove
🌐 Data from online sources
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

def remove_elements(head, val):
    sentinel = ListNode(0)
    sentinel.next = head
    prev, curr = sentinel, head

    while curr:
        if curr.val == val:
            prev.next = curr.next
        else:
            prev = curr
        curr = curr.next

    return sentinel.next

The algorithm for removing elements with a specific value from a linked list involves iterating through the list and maintaining two pointers prev and curr. The prev pointer will point to the previous node in the list, whereas the curr pointer will point to the current node that is being processed.

  • First, create a sentinel node to handle edge cases for the head node.
  • Assign the next attribute of the sentinel node to the given head node.
  • Set the prev pointer to the sentinel node and the curr pointer to the head node.
  • Loop through the linked list:
  • If the value of the current node matches the given value, remove it by updating the next attribute of the previous node.
  • Otherwise, move the prev pointer to the current node.
  • Move the curr pointer to the next node.
  • After the loop, the new head of the linked list is found in the sentinel node's next attribute.

Note that in C++, due to manual memory management, we have to delete the nodes to avoid memory leaks.

🌐 Data from online sources
class ListNode {
public:
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(NULL) {}
};

ListNode* removeElements(ListNode* head, int val) {
    ListNode** current = &head;

    while (*current != NULL) {
        if ((*current)->val == val) {
            ListNode* next = (*current)->next;
            delete *current;
            *current = next;
        } else {
            current = &(*current)->next;
        }
    }

    return head;
}

The algorithm for removing elements with a specific value from a linked list involves iterating through the list and maintaining two pointers prev and curr. The prev pointer will point to the previous node in the list, whereas the curr pointer will point to the current node that is being processed.

  • First, create a sentinel node to handle edge cases for the head node.
  • Assign the next attribute of the sentinel node to the given head node.
  • Set the prev pointer to the sentinel node and the curr pointer to the head node.
  • Loop through the linked list:
  • If the value of the current node matches the given value, remove it by updating the next attribute of the previous node.
  • Otherwise, move the prev pointer to the current node.
  • Move the curr pointer to the next node.
  • After the loop, the new head of the linked list is found in the sentinel node's next attribute.

Note that in C++, due to manual memory management, we have to delete the nodes to avoid memory leaks.