力扣题目链接
给你一个链表,删除链表的倒数第 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]
思路
思路1:设置两个指针,指针指向元素节点间隔为n(例如:当n=1,p指针指向空结束时,q指针刚好在待删除节点前),利用前一个指针删除元素,注意特殊情况。
思路2:遍历第一遍,得到元素个数,遍历第二遍删除目标元素。
解法1
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
//创建头指针
struct ListNode *L;
L = (struct ListNode*)malloc(sizeof(struct ListNode));
L->next = head;
struct ListNode *p,*q,*tmp;
p = head;
q = L; //待删除节点的前一个节点
int flat = 0;
if(head==NULL||head->next==NULL&&n==1) //特殊情况返回NULL
{
return NULL;
}
while(p)
{
if(flat>=n)
{
q = q->next;
}
flat++;
p = p->next;
}
if(flat>n) //正常情况
{
tmp = q->next;
q->next = tmp->next;
free(tmp);
}
else //边界条件 即删除第一个元素的条件
{
tmp = head;
L->next = head->next;
free(tmp);
}
head = L->next;
free(L);
return head;
}
- 时间复杂度 O(n)
- 空间复杂度 O(1)
小结:需要考虑为空的情况,以及删除倒数第n个节点(第一个元素,该情况使用L头指针)。