链表:删除

2021-06-24 每日一题 LeetCode

# 0019. 删除链表的倒数第 N 个结点 (opens new window)

题目

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

示例 1:

输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
1
2

示例 2:

输入:head = [1], n = 1
输出:[]
1
2

示例 3:

输入:head = [1,2], n = 1
输出:[1]
1
2

提示:

  • 链表中结点的数目为 sz
  • 1 <= sz <= 30
  • 0 <= Node.val <= 100
  • 1 <= n <= sz

进阶:你能尝试使用一趟扫描实现吗?

解析

快慢双指针,令快指针先走 n 步,之后两指针再同步移动,直到快指针移动到链表结尾,此时慢指针指向的下一个位置即为要删除元素。

注意

  • 在头部插入一个虚拟结点,可以避免对头结点的特殊处理。
  • 边界情况可以测试几个 case 确定。

代码

    # 0082. 删除排序链表中的重复元素 II (opens new window)

    题目

    存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中 没有重复出现 的数字。

    返回同样按升序排列的结果链表。

    解析

    由于头结点可能被删除,因此需要一个增加一个虚拟结点。

    遍历链表,当遇到重复结点时,循环向后移动,直到下一个不重复结点,将中间结点删除即可。

    代码

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode() : val(0), next(nullptr) {}
     *     ListNode(int x) : val(x), next(nullptr) {}
     *     ListNode(int x, ListNode *next) : val(x), next(next) {}
     * };
     */
    class Solution {
    public:
        ListNode* deleteDuplicates(ListNode* head) {
            ListNode *dummy = new ListNode(0), *p = dummy;
            dummy->next = head;
            while (p->next) {
                ListNode *q = p->next;
                while (q->next && q->next->val == q->val) q = q->next;
                if (q == p->next) p = p->next;
                else p->next = q->next;
            }
            return dummy->next;
        }
    };
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24

    # 0083. 删除排序链表中的重复元素 (opens new window)

    题目

    存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除所有重复的元素,使每个元素 只出现一次 。

    返回同样按升序排列的结果链表。

    解析

    用一个指针来遍历链表,每遍历到一个节点,就用另一个指针来找到后面第一个和当前节点值不同的节点,然后把中间的重复节点全部删去,重复这个过程,直至链表结尾。

    代码

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode() : val(0), next(nullptr) {}
     *     ListNode(int x) : val(x), next(nullptr) {}
     *     ListNode(int x, ListNode *next) : val(x), next(next) {}
     * };
     */
    class Solution {
    public:
        ListNode* deleteDuplicates(ListNode* head) {
            ListNode *p = head;
            while (p && p->next) {
                ListNode *q = p->next;
                while (q && q->val == p->val) q = q->next;
                p->next = q;
                p = p->next;
            }
            return head;
        }
    };
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23

    # 0203. 移除链表元素 (opens new window)

    题目

    给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。

    解析

    由于头结点可能被删除,因此增加一个虚拟结点,遍历链表,当 next 结点值为 val 时,跳过该结点,直至链表结尾。

    代码

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode() : val(0), next(nullptr) {}
     *     ListNode(int x) : val(x), next(nullptr) {}
     *     ListNode(int x, ListNode *next) : val(x), next(next) {}
     * };
     */
    class Solution {
    public:
        ListNode* removeElements(ListNode* head, int val) {
            ListNode* dummy = new ListNode(0);
            dummy->next = head;
            
            ListNode* p = dummy;
            while (p->next) {
                if (p->next->val == val) {
                    p->next = p->next->next;
                } else {
                    p = p->next;
                }
            }
            return dummy->next;
        }
    };
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27

    # 0237. 删除链表中的节点 (opens new window)

    题目

    请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点。传入函数的唯一参数为要被删除的节点。

    解析

    由于本题没有给出链表的头节点,可以换一种思路,将下一个节点的 val 复制到被删除节点上,同时被删除节点指向下下个节点。

    代码

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        void deleteNode(ListNode* node) {
            node->val = node->next->val;
            node->next = node->next->next;
        }
    };
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Last Updated: 2023-01-28 4:31:25