leetcode每日一练-第19题-删除链表的倒数第 N 个结点

leetcode每日一练-第19题-删除链表的倒数第 N 个结点_第1张图片

 一、思路

双指针

二、解题方法

首先创建一个哑节点dummy便于操作链表

然后创建两个指针slow和fast,开始时两个指针都指向dummy地址,fast先向前移动n+1个单位

然后同时操作slow和fast,利用fast移动到链表末尾的长度=slow移动到倒数n+1个位置的长度

最后删除倒数第n个节点,使倒数第n+1个节点直接指向倒数第n个的后面一个节点。

leetcode每日一练-第19题-删除链表的倒数第 N 个结点_第2张图片

三、code

/**
 * 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* removeNthFromEnd(ListNode* head, int n) {
        //通过创建名为 dummy 的节点对象,并将其初始化为值为 0 的节点,我们可以使用该节点作为链表的虚拟头结点。虚拟头结点不存储实际的数据,只用于方便操作链表,例如在删除头结点或者删除倒数第 n 个节点时,可以避免特殊处理。
        ListNode dummy(0);
        dummy.next=head;

        ListNode* fast = &dummy;将虚拟头结点 dummy 的地址赋值给指针变量 fast。这样,fast 指针就指向了虚拟头结点 dummy
        //通过将 fast 指针初始化为虚拟头结点 dummy 的地址,我们可以在后续的操作中使用 fast 指针来遍历链表,并且不会影响到真正的头结点 head。
        ListNode* slow = &dummy;
        for(int i=0;inext;
        }

        while(fast)// 同时移动 fast 和 slow 指针,直到 fast 到达链表末尾
        {
            fast=fast->next;
            slow=slow->next;//此时,slow 指针指向的节点就是倒数第 n+1 个节点,即要删除节点的前一个节点。
        }

        // 删除倒数第 n 个节点,并更新 slow->next 指向删除节点的下一个节点。释放被删除节点的内存空间。
        ListNode* toDelect=slow->next;
        slow->next=slow->next->next;
        delete toDelect;

        return dummy.next;//返回虚拟头结点的下一个节点作为链表的新头结点

    }
};

=========================================================================学到的知识:

①ListNode dummy(0);

是创建了一个名为 dummy 的节点对象,并初始化其值为 0。 

②ListNode* fast = &dummy;

的作用是将指针 fast 初始化为指向虚拟头结点 dummy 的地址。

你可能感兴趣的:(c++)