题目描述
19. 删除链表的倒数第 N 个结点
难度中等2410收藏分享切换为英文接收动态反馈
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
示例 1:
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例 2:
输入:head = [1], n = 1
输出:[]
示例 3:
输入:head = [1,2], n = 1
输出:[1]
提示:
链表中结点的数目为 sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
普通思路:
思路:1.首先定义一个头节点dummy(有人知道为什么要定义这个头节点吗?答案是:因为我们不知道第一个元素是不是要删除的第N个元素 所以要建立一个头节点。如果没理解 那就结合下面代码 看看第一个节点之后的节点是怎么删除的)
2.接着创建一个指针 cur ,
3.让cur指向被删元素的前一个结构体地址 再将删除元素后面的地址赋给删除元素前一个地址(跳过被删除元素)
4.最后返回头节点地址,最后一步是有点多余。
int Length(struct ListNode* head)
{
int len = 0;
while(head)
{
len++;
head = head->next;
}
return len;
}
struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
struct ListNode* dummy = malloc(sizeof(struct ListNode));
dummy->val = 0,dummy->next = head;
int len = Length(head);
struct ListNode* cur = dummy;
for(int i = 1;i<len-n+1;i++)
{
cur = cur->next;
}
cur->next = cur->next->next;
struct ListNode* ans = dummy->next;
return ans;
}
快慢指针
struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
struct ListNode *quick = head, *slow = head;
int i;
for (i = 0; i <= n && quick; ++i)//先让快指针先走n步
quick = quick->next;
if (i <= n)//如果倒数第n个节点的大小 大于i
{
head = head->next;
return head;
}
//快慢指针同时走 那个慢指针就在被删节点的前面
while (quick) {
slow = slow->next;
quick = quick->next;//关键在这 如果理解 就没问题
}
slow->next = slow->next->next;//这个代码实现方式和第一个代码实现方式不一样 我感觉基本思路都一样
return head;
}
总结:以上两个代码只是实现方式不太一样 我认为思想是一样大(将被删元素跳过 将被删元素的前后节点相连接)
如果老铁有其他解法 相互分享~