一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第一天,点击查看活动详情。
题目来源:力扣(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;
}