Linked List

Today, let's talk about Linked List algorithms that are frequently used.

A Linked List is a data structure that stores data into a series of connected nodes, and thus it can be dynamically allocated. For each node, it contains 2 fields: the val that stores data, and the next that points to the next node.

In LeetCode, the Linked List is often defined below, using C++:

1struct ListNode {
2    int val;
3    ListNode *next;
4};

The content of this blog is shown below:

mindmap
root)Linked List(
        A1(Node Removal)
        A2(Inplace Reversal)
        A3(Merge)
        A4(Insertion Sort)
        A5(Two Pointer)

Node Removal

LeetCode 203: 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.

 1ListNode* removeElements(ListNode* head, int val){
 2    ListNode newHead;
 3    ListNode  *pre = &newHead;
 4    newHead.next = head;
 5
 6    while (pre->next != nullptr ) {
 7        ListNode *cur = pre->next;
 8        if (cur->val == val ) {
 9            pre->next = cur->next;
10            delete cur;
11        }else
12            pre = pre->next;
13    }
14    return newHead.next;
15}

In-place Reversal

LeetCode 206. Reverse Linked List

Given the head of a singly linked list, reverse the list, and return the reversed list.

1ListNode* reverseList(ListNode* head) {
2    ListNode *pre = nullptr, *cur = head;
3    while (cur != nullptr ) {
4        ListNode *next = cur->next;
5        cur->next = pre;
6        pre = cur, cur = next;
7    }
8    return pre;
9}

Merge

LeetCode 21. Merge Two Sorted Lists

You are given the heads of two sorted linked lists list1 and list2.

Merge the two lists in a one sorted list. The list should be made by splicing together the nodes of the first two lists.

Return the head of the merged linked list.

 1ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
 2    ListNode head;
 3    ListNode *pre = &head;
 4
 5    while (list1 != nullptr && list2 != nullptr ) {
 6        if (list1->val < list2->val ) {
 7            pre->next = list1;
 8            list1 = list1->next;
 9        } else {
10            pre->next = list2;
11            list2 = list2->next;
12        }
13        pre = pre->next;
14    }
15
16    while (list1 != nullptr ) {
17        pre->next = list1;
18        pre = pre->next;
19        list1 = list1->next;
20    }
21
22    while (list2 != nullptr ) {
23        pre->next = list2;
24        pre = pre->next;
25        list2 = list2->next;
26    }
27    pre->next = nullptr;
28    return head.next;
29}

Insertion Sort

LeetCode 147. Insertion Sort List

Given the head of a linked list, return the list after sorting it in ascending order.

Given the head of a singly linked list, sort the list using insertion sort, and return the sorted list's head.

The steps of the insertion sort algorithm:

  1. Insertion sort iterates, consuming one input element each repetition and growing a sorted output list.
  2. At each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list and inserts it there.
  3. It repeats until no input elements remain.
 1ListNode* insertionSortList(ListNode* head) {
 2    if (head == nullptr) return head;
 3    ListNode tmpHead;
 4    ListNode *cur = head, *pre = &tmpHead;
 5
 6    while (cur != nullptr) {
 7        while (pre->next != nullptr && pre->next->val < cur->val)
 8            pre = pre->next;
 9
10        ListNode* next = cur->next;
11        cur->next = pre->next;
12        pre->next = cur;
13        pre = &tmpHead;
14        cur = next;
15    }
16    return tmpHead.next;
17}

Two Pointer

We often use fast and slow to solve Linked List problems in $O(n)$-time complexity.

Middle Node

LeetCode 876. Middle of the Linked List

Given the head of a singly linked list, return the middle node of the linked list.

If there are two middle nodes, return the second middle node.

1ListNode* middleNode(ListNode* head) {
2    ListNode *fast = head, *slow = head;
3    while (fast != nullptr && fast->next != nullptr) {
4        fast = fast->next->next;
5        slow = slow->next;
6    }
7    return slow;
8}

Cycle Detection

LeetCode 142. Linked List Cycle II

Given the head of a linked list, return the node where the cycle begins. If there is no cycle, return null.

Do not modify the linked list.

 1ListNode *detectCycle(ListNode *head) {
 2    ListNode *fast = head, *slow = head;
 3
 4    // Judge if cycle exists
 5    while ( true ) {
 6        if (fast == nullptr || fast->next == nullptr )
 7            return nullptr;
 8        fast = fast->next->next;
 9        slow = slow->next;
10        if (fast == slow) break;  // Cycle detect
11    }
12
13    // yes there is a cycle, and find the entry of cycle
14    ListNode *ptr = head;
15    while (ptr != slow ) {
16        ptr = ptr->next;
17        slow = slow->next;
18    }
19    return ptr; 
20}

* This blog was last updated on 2023-04-05 22:22