leetcode[#19 链表 标尺]Remove Nth Node From End of List

Given a linked list, remove the nth node from the end of list and return its head.

For example,

   Given linked list: 1->2->3->4->5, and n = 2.

   After removing the second node from the end, the linked list becomes 1->2->3->5.

Note:
Given n will always be valid.
Try to do this in one pass.

其实关键就是找到要删除的倒数第n个节点。更简单的问题,让你通过一次遍历找到链表的中间节点,设置两个指针,一个每次移动2个节点,一个每次移动一个节点,当快指针为NULL时,慢指针的位置就是中间节点的位置。怎么找到倒数第n个点呢,还是设两个指针,让一个指针先移动n的节点,然后让另一个指针从头指针开始和它一起移动,当先移动的为NULL时,后移动的就是要被删除的元素,需要保存下它的前一个指针。如果第一个指针移动n个节点之后已经是NULL了,也就是移动了链表长度n次,那么要删除的元素就是第一个节点。

不管是顺数n个还是倒数n个,其实都是距离-标尺问题。标尺是一段距离可以用线段的两个端点来衡量。如果我们用两个指针,并保持他们的距离为n,那么当这个线段的右端指向末尾节点时,左端节点就指向倒数第n个节点。


class Solution {
public:
    ListNode *removeNthFromEnd(ListNode *head, int n) {
        ListNode *first = head;
        ListNode *second = head;
        ListNode *del = NULL;
        ListNode *presecond = head;
        while(NULL != first && n>0)
        {
            first = first->next;
            n --;
        }
        if(NULL == first)
        {   
            del = head;
            head = head->next;
            delete del;
            return head;
        }
        
        while(NULL != first)
        {
            first = first->next;
            presecond = second;
            second = second ->next;
        }
        del = second ;
        presecond->next = second->next;
        delete del;
        return head;
    }
};

增加一个表头节点,这样就不用区分要删除的是第一个节点,表头节点的作用就是让删除或者在第一个节点前插入节点易于操作。

 
 
class Solution {
public:
ListNode * removeNthFromEnd ( ListNode * head , int n ) {
ListNode new_head ( - 1 );
new_head . next = head ;
ListNode * front = & new_head , * rear = & new_head ;
for ( int i = 0 ; i < n ; i ++ )
front = front -> next ;
while ( front -> next != NULL ) {
front = front -> next ;
rear = rear -> next ;
}
ListNode * tmp = rear -> next ;
rear -> next = rear -> next -> next ;
delete tmp ;
head = new_head . next ;
return head ;
}
};




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值