题目
双指针实现
三步走:
1.先让快指针,向前移动n步。
2.让两者同时移动直到快指针到达尾部,慢指针所指即为倒数第n+1。
3.考虑特殊情况删除倒数第n个。
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* l = head;
ListNode* r = head;
int count = 0;
//r指针前移n步
while(count<n){
r=r->next;
count++;
}
//当r节点等于NULL,说明是删除倒数第节点总数的那一个,即删除头节点。
if(r==NULL)
return head->next;
//找到倒数第n+1个节点而不是导数第n个
while(r->next!=NULL){
l=l->next;
r=r->next;
}
l->next = l->next->next;
return head;
}
};
递归实现
在正式代码前我们,先实现用递归得到链表的长度这一操作:
int length(Listnode* node){
if(node == NULL)return 0;
int pos = length(node->next)+1;
return pos;
}
很明显这是一个递归树的后序遍历,从反方向上来讲,它是从倒数第0(节点为NULL)往前不断的递增,所以我们可以在后序遍历的中途加上一项判断,然后执行相应的操作即可。
递归实现
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
int pos = length(head, n);
// 说明删除的是头节点
if (pos == n)
return head->next;
return head;
}
private://在获取长度的后序遍历途中,加入一个判断,对倒数第n+1的节点进行操作,便可以将倒数第n个节点删除了。但是。。还有特殊情况,比如倒数第n个我们就没法得到其n+1的节点了,这时候就需要在主函数操控了。
int length(ListNode* node, int n) {
if (node == NULL)
return 0;
int pos = length(node->next, n) + 1;
//获取要删除链表的前一个结点,就可以完成链表的删除
if (pos == n + 1)
node->next = node->next->next;
return pos;
}
};