[链表]-19. 删除链表的倒数第N个节点

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

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.

说明:
给定的 n 保证是有效的。

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


解析:

首先需要考虑的是找到倒数第n个节点。指针q先确定倒数第N个节点的位置,它先走n步。再利用两个指针同时跑(p指针从头节点开始),当q指针跑完指向NULL时,此时p指针的位置就是待删节点的位置。为了删除待删节点,它必须有前驱指针,在遍历中记录就可以。ps:当q初始位置找到后为NULL时说明,n等于链表节点数,删除倒数第n个就是删除第一个节点。


[链表]-19. 删除链表的倒数第N个节点_第1张图片
起始

[链表]-19. 删除链表的倒数第N个节点_第2张图片
q向前走了n-1步

[链表]-19. 删除链表的倒数第N个节点_第3张图片
q为NULL时,此时p为待删节点,t为待删节点的前驱

C代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
    if( head == NULL) return head;//非空判断
    struct ListNode *p=NULL;
    struct ListNode *t=NULL;
    struct ListNode *q=head->next;
    //q向前走n-1步
    for(int i=0;inext;
    }
    //对q进行非空判断
    if(q==NULL){
        t=head->next;
        free(head);
        return t; 
    } 
    //利用for死循环找到p的位置,
    for(p=head; q!=NULL ;t=p,p=p->next,q=q->next);
    t->next=p->next;
    free(p);
    return head;
}

你可能感兴趣的:([链表]-19. 删除链表的倒数第N个节点)