题目描述:
给定一个链表,删除链表的倒数第 n
个结点,并且返回链表的头结点。(难度中等)
算法思路:
求出链表的长度(getLength)保证n在链表的长度范围内。
定义快指针先走n步
然后快、慢指针一起走
当快指针的下一个到NULL时,慢指针指向要删除的节点的直接前驱。
这个题力扣官方的双指针法添加了一个哑节点作为头节点,其实也可以不用那样建立新节点再删除。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
int getLength(struct ListNode* head) {
if(head==NULL)
return NULL;
int count = 0;
struct ListNode*p = head;
while (p!=NULL)
{
count++;
p = p->next;
}
return count;
}
struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
if(head==NULL)
return NULL;
if(n<0||n>getLength(head))
return NULL;
struct ListNode *fast = head;
struct ListNode *slow = head;
for(int i=0;i<n;i++)
{
fast = fast->next;
}
if(fast==NULL)//如果快指针指向NULL,说明删除head
return head->next; //直接返回head后面的链
while(fast->next!=NULL)
{
fast = fast->next;
slow = slow->next;
}
slow->next = slow->next->next;
return head;
}
复杂度分析
时间复杂度:O(L),其中 将L 是链表的长度。
空间复杂度:O(1)
没有头节点不太习惯,第一次大概看了一下题按有头节点写的,结果删除第一个值的测试一直通过不了(因为计算的链表长度不对)然后看了半天才发现题目没有头节点……