19.删除链表的倒数第n个节点

143 阅读2分钟

19.删除链表的倒数第n个节点

LeetCode


描述:

image-20220405150844287


思路:

  • 如果将这个题中的链表看做为数组, 解题方法将很简单, 但是链表相对于数组, 无法直接知道链表的长度和链表每个元素的下标, 只有根据每个元素的指针域进行遍历, 此题即考察这一点.
  • 理所当然的, 可以想到, 先获取链表的整体长度len, 之后遍历至len - n + 1将此处的元素删除即可.
  • 另一种思路双指针法, 快指针先移动n + 1个位置, 此时快指针和慢指针之间即相隔n个元素, 之后进行遍历, 快指针和慢指针同时移动, 到快指针指向null时, 慢指针即指向待删除的元素, 遍历结束, 删除慢指针指向的元素即可.

代码:

  1. 求链表长度法

    /*
     * @lc app=leetcode.cn id=19 lang=cpp
     *
     * [19] 删除链表的倒数第 N 个结点
     */
    
    // @lc code=start
    /**
     * 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:
        int getLength(ListNode *head)
        {
            int length = 0;
            while (head->next != nullptr)
            {
                head = head->next;
                length++;
            }
            return length;
        }
    
        ListNode *removeNthFromEnd(ListNode *head, int n)
        {
            ListNode *dummy = new ListNode(0, head);
            int ListNodeLen = getLength(head);
    
            ListNode *cur = dummy;
            for (int i = 0; i < ListNodeLen - n + 1; i++)
            {
                cur = cur->next;
            }
    
            cur->next = cur->next->next;
            ListNode *result = dummy->next;
            delete dummy;
            return result;
        }
    };
    

  2. 双指针法:

    /*
     * @lc app=leetcode.cn id=19 lang=cpp
     *
     * [19] 删除链表的倒数第 N 个结点
     */
    
    // @lc code=start
    /**
     * 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)
        {
            ListNode *fast = head;
            ListNode *slow = head;
            for (int i = 0; i < n; i++)
            {
                fast = fast->next;
            }
    
            if (fast == nullptr)
            {
                return head->next;
            }
    
            while (fast->next != nullptr)
            {
                fast = fast->next;
                slow = slow->next;
            }
    
            slow->next = slow->next->next;
            return head;
        }
    };