【Leetcode】【链表】 19. Remove Nth Node From End of List / 删除链表的倒数第N个节点】

Given a linked list, remove the n-th node from the end of list and return its head.

Example:

Given linked list: 1->2->3->4->5, and n = 2.

After removing the second node from the end, the linked list becomes 1->2->3->5.

Note:

Given n will always be valid.

Follow up:

Could you do this in one pass?


此题类似于求解链表的倒数第n个节点。分析如下



(图示一)同样是使用两个指针来获得链表的倒数第n个节点,但我们这个题目是要删除倒数第n个节点,所以使用pPre指针指向欲删除节点的前一个节点。这样最终我们得到欲删除节点的前一处(pPre)位置时,使 pPre->next 指向 pPre->next->next (欲删除节点的下一个节点),即跳过欲删除节点。 

(图示二)注意到此题是返回删除后的链表,return为链表的头节点。而头节点也可能被删除。所以当pAhead指向为空时说明n等于链表长度,即欲删除节点为头节点,此时返回head->next即可。


之前做删除节点时,使用的是“狸猫换太子”,将欲删除节点的值换为后一个节点的值,再跳过后一个节点。而此题我们可以轻易得到与删除节点的上一个节点,所以直接在上一个节点进行跳过欲删除节点即可。

pPre指针指向欲删除节点的前一个节点,所以在pAhead先走时,可以先走一步,这样后面同时移动后,pPre就是倒数第n个节点的上一个节点了。

    ListNode* removeNthFromEnd(ListNode* head, int n) {
        if(head == nullptr)
            return nullptr;
        if(n<=0)                // n输入非法
            return head;
        ListNode* pPre = head;      // 倒数第n个节点的前一个,方便进行删除操作
        ListNode* pAhead = head;    // 先行节点
        for(int i=0; i<n; i++) {    // 正常应该少移动一位,但是这里我们欲得到pPre为删除节点的前一个节点
            pAhead = pAhead->next;
        }
        if(pAhead == nullptr)               // n=链表长度,此时删除的是头节点
            return head->next;
        while(pAhead->next != nullptr) {    // pPre和pAhead同时移动
            pPre = pPre->next;
            pAhead = pAhead->next;
        }
        pPre->next = pPre->next->next;        // 跳过pPre->next(要删除的节点)
        return head;
    }



猜你喜欢

转载自blog.csdn.net/weixin_38628152/article/details/80317332