每日一算:链表操作

删除链表中倒数第N个元素

终于过渡到链表了。。。(感慨一下)
你是否还在坚持学?

近日,LC上某题引起了我的关注。
题目:给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。

那么一本题为例,分析一下:
采取双重遍历肯定是可以解决问题的,但题目要求我们一次遍历解决问题,那我们的思路得发散一下。
我们可以设想假设设定了双指针p和q的话,当q指向末尾的NULL,p与q之间相隔的元素个数为n时,那么删除掉p的下一个指针就完成了要求。
1.设置虚拟节点dummyHead指向head
2.设定双指针p和q,初始都指向虚拟节点dummyHead
3.移动q,直到p与q之间相隔的元素个数为n
4.同时移动p与q,直到q指向的为NULL将p的下一个节点指向下下个节点

动画演示:
每日一算:链表操作

代码描述(c++):

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode * dHead = new ListNode(0);
        dHead -> next = head;
        ListNode * p = dHead;
        ListNode * q = dHead;
        for(int i = 0 ; i < n + 1 ; i ++){
            assert(q);
            q=q->next;
        }
        while(q){
            p=p->next;
            q=q->next;
        }
        ListNode * delNode=p->next;
        p->next=delNode->next;
        delete delNode;
        
        ListNode * pNode=dHead->next;
        delete dHead;
        
        return pNode;
    }
};

代码部分结合上面分析去看,更好理解一些!