删除链表的倒数第N个结点
题目解析:
思路一:(带有头节点的版本)
采取双重遍历肯定是可以解决问题的,但题目要求我们一次遍历解决问题,那我们的思路得发散一下。 我们可以设想假设设定了双指针 p 和 q 的话,当 q 指向末尾的 NULL,p 与 q 之间相隔的元素个数为 n 时,那么删除掉 p 的下一个指针就完成了要求。 设置虚拟节点 dummyHead 指向 head 设定双指针 p 和 q,初始都指向虚拟节点 dummyHead 移动 q,直到 p 与 q 之间相隔的元素个数为 n 同时移动 p 与 q,直到 q 指向的为 NULL 将 p 的下一个节点指向下下个节点 让快慢指针相差n个位置,当快指针到最后一个元素时,慢指针的下一个元素正好就是要删除的元素
代码如下所示:
class Solution {
public:
ListNode* removeNthFromEnd ( ListNode* head, int n)
{
ListNode * start = new ListNode ( - 1 ) ;
start-> next = head;
ListNode * slow = start , * fast = start , * temp;
for ( int i = 1 ; i <= n ; i++ )
{
fast = fast-> next;
}
while ( fast-> next)
{
slow = slow-> next;
fast = fast-> next;
}
temp= slow-> next;
slow-> next= slow-> next-> next;
delete temp;
return start-> next;
}
} ;
思路二:(不带头节点的版本)
class Solution {
public:
ListNode* removeNthFromEnd ( ListNode* head, int n) {
ListNode * slow = head , * fast = head;
ListNode * temp;
for ( int i = 1 ; i <= n ; i++ )
fast = fast-> next;
if ( fast == NULL )
{
temp = head-> next;
delete head;
return temp;
}
while ( fast-> next)
{
slow = slow-> next;
fast = fast-> next;
}
temp= slow-> next;
slow-> next= slow-> next-> next;
delete temp;
return head;
}
} ;
思路三:递归
class Solution {
public:
int cur= 0 ;
ListNode* removeNthFromEnd ( ListNode* head, int n)
{
if ( nullptr== head)
return NULL ;
head-> next = removeNthFromEnd ( head-> next, n) ;
if ( n == ++ cur)
return head-> next;
return head;
}
} ;