Loading

07 删除链表

1 删除链表中的节点

image
image
image
image
image

1.1 解题思路

由于要删除的节点一定不是末尾节点,且又不能存在于链表中。所以我们的做法可以是:将nodenext指针所指向的下一个节点的值赋值给node,删除node->next即可。

1.2 代码实现

点击查看代码
class Solution {
public:
    void deleteNode(ListNode* node) {
        if (node != nullptr && node->next != nullptr) {
            ListNode* nxt = node->next;
            node->val = nxt->val;
            node->next = nxt->next;
            delete nxt;   
        }
    }
};
  • 时间复杂度:$$O(1)$$
  • 空间复杂度:$$O(1)$$

2 删除链表的倒数第N个节点

image
image

2.1 解题思路

要想删除倒数第n个节点,我们要找到倒数第n + 1个节点。
初始化快慢指针都指向dummy_node,先让右指针走n步,然后左右指针一起向右走,因此左右指针的距离为n
当右指针指向最后1个节点,也即倒数第1个节点时,左(慢)指针刚好指向倒数第n + 1个节点。
下面这份代码是我在没有看讲解前写的,因为之前做过一编,大致的思路还有点印象。

2.2 代码实现

点击查看代码
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* dummy_head = new ListNode(0, head);
        ListNode* fast = dummy_head, * slow = fast;
        for (int i = 0; i < n + 1; ++i) {
            fast = fast->next;
        }
        while (fast != nullptr) {
            fast = fast->next;
            slow = slow->next;
        }
        ListNode* nxt = slow->next;
        slow->next = nxt->next;
        delete nxt;
        return dummy_head->next;
    }
};
  • 时间复杂度:$$O(n)$$
  • 空间复杂度:$$O(1)$$

3 删除排序链表中的重复元素

image
image

3.1 解题思路

3.2 代码实现

点击查看代码
class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if (head == nullptr) {
            return head;
        }
        ListNode* left = head, * right = head->next;
        while (right != nullptr) {
            if (right->val != left->val) {
                left = left->next;
                left->val = right->val;
            }
            right = right->next;
        }
        while (left->next != nullptr) {
            ListNode* nxt = left->next->next;
            delete left->next;
            left->next = nxt;
        }  
        return head; 
    }
};
- 时间复杂度:$$O(n)$$ - 空间复杂度:$$O(1)$$

4 删除链表中的重复元素 II

image
image

4.1 解题思路

因为这道题目已经说明删除重复的数字,所以需要dummy node
初始化cur指针指向dummy_node,每次循环时看下一个节点和下下一个节点是不是一样的,如果是,说明重复,都要删除掉。
这里如果重复的,我们需要再套一个循环,直到遇到不一样的节点。

4.2 代码实现

点击查看代码
class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if (head == nullptr) {
            return head;
        }
        ListNode* dummy_head = new ListNode(0, head);
        ListNode* cur = dummy_head, * nxt = cur->next;
        while (nxt != nullptr && nxt->next != nullptr) {
            int val = nxt->val;
            if (nxt->next->val == val) {
                while (nxt != nullptr && nxt->val == val) {
                    cur->next = nxt->next;
                    delete nxt;
                    nxt = cur->next;
                }   
            } else {
                nxt = nxt->next;
                cur = cur->next;
            }
        }
        return dummy_head->next;  
    }
};
  • 时间复杂度:$$O(n)$$
  • 空间复杂度:$$O(1)$$
posted @ 2026-01-01 09:43  王仲康  阅读(3)  评论(0)    收藏  举报