删除列表的倒数第N个结点

201 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第一天,点击查看活动详情

参考:作者:LeetCode-Solution

题目来源:力扣(LeetCode)

题目

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

示例 1:

输入:head = [1,2,3,4,5], n = 2 输出:[1,2,3,5] 示例 2:

输入:head = [1], n = 1 输出:[]

输入:head = [1,2], n = 1 输出:[1]

思路

首先最先想到的就是先计算链表长度,不知道长度怎么能确定我们要删除的元素位置呢,因此我们首先从头节点开始对链表进行一次遍历,得到链表的长度 length。随后我们再从头节点开始对链表进行一次遍历,当遍历到第 L-n+1个节点时,它就是我们需要删除的节点。

为了与题目中的 n 保持一致,节点的编号从 1 开始,头节点为编号 1 的节点。

为了方便删除操作,我们可以从哑节点开始遍历 L-n+1 个节点。当遍历到第 L-n+1 个节点时,它的下一个节点就是我们需要删除的节点,这样我们只需要修改一次指针,就能完成删除操作。

代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
    struct ListNode *p;
    p = head;
    int i,length = 1;
    while(p->next!=NULL){
        p = p->next;
        length++; //得到总长度
    }
    p = head;
    for(i = 1; i < length - n; i++){
        p = p->next;
    }
    //根据题目分的三种情况
    if(length == 1){ //当只有一个结点时
        head = NULL; 
    }
    else if(length == n){ //当数组长度等于删除结点倒数的索引时,相当于待删除的是头结点
        head = head->next;
    }
    else{
        p->next = p->next->next;  //一般情况下时
    }
    return head;
}