Skip to content
DSA Essentials
GitHub

Remove Last

  • Removes last element (element referenced by tail) from linked list
public Node removeLast() {
}

Case: Linked List is empty

Simply return null as there is no element to delete.

public class LinkedList {
    
    public Node removeLast() {
        if (length == 0) {
            return null;
    }
}

Case: Linked List is not empty

Linked list

To get to the last node, you need to start with head and navigate along its next value. You repeat this process until the next value is null.

While removing the last element, you also need to keep track of second last node as tail needs to point to this node (remember tail always points to last node).

public class LinkedList {
    
    public Node removeLast() {
        if (length == 0) {
            return null;
        } else {
            Node pre = head; // holds node before curr (eventually second last element)
            Node curr = head; // holds current node (eventually last element)
            while (last.next != null) {
                pre = curr;
                curr = curr.next;
            }
        }
    }
}

Let’s have a closer look at while block

Node pre = head;
Node curr = head;
while (curr.next != null) {
    pre = curr;
    curr = curr.next;
}

This code block basically navigates along head’s next and its next and so on until it encounters null (i.e. end of linked list).

Step One

Initially pre (second last) and curr (last) both starts from first node. Linked list remove last

Step Two

Linked list remove last

Step Three

Linked list remove last

Step Four

Linked list remove last

After this step condition curr.next != null doesn’t satisfy as curr points to node with value 4 whose next’s is null. At this stage you have the last and second last element, only thing left now is to set the second last node’s next (pre’s next) to null.

pre.next = null;

Since pre is now the last element, tail must also reference to pre.

tail = pre;

Also, decrement the length of linked list.

length--;

Linked list remove last

Combine the above logic.

public class LinkedList {
    
    public Node removeLast() {
        if (length == 0) {
            return null;
        } else {
            Node pre = head; // holds node before curr (eventually second last element)
            Node curr = head; // holds current node (eventually last element)
            while (last.next != null) {
                pre = curr;
                curr = curr.next;
            }
            pre.next = null;
            tail = pre;
            length--;
            return curr; // returning the removed node
        }
    }
}

You also need to handle another edge case when linked list contains exactly one element. In such case simply set head and tail to null.

public class LinkedList {
    
    public Node removeLast() {
        if (length == 0) {
            return null;
        } else {
            Node pre = head;
            Node curr = head;
            while (last.next != null) {
                pre = curr;
                curr = curr.next;
            }
            pre.next = null;
            tail = pre;
            length--;
            if (length == 0) { // since length is decremented by 1 above, it means linked list had length 1
                head = null;
                tail = null;
            }
            return curr; 
        }
    }
}

Testing

public class LinkedListTest {

    @Test
    void removeLast() {
        LinkedList linkedList = new LinkedList();
        //  remove from empty linked list should return null
        assertNull(linkedList.removeLast());

        // remove when list consists one element
        linkedList.append(1);
        linkedList.removeLast();
        assertEquals(0, linkedList.getLength());

        // remove on list with length greater than one
        linkedList.append(1);
        linkedList.append(2);
        linkedList.append(3);
        linkedList.append(4);
        var temp = linkedList.removeLast();
        assertEquals(3, linkedList.getLength());
        assertEquals(4, temp.getValue());
        assertEquals(List.of(1, 2, 3), convertToArrayList(linkedList));
    }
}

Time complexity

Removing an element from the end of a linked list has linear worst-case time complexity - O(n) as you need to navigate linked list to find last node.