OJ练习8——T19 remove nth node

删除链表倒数第n个节点,返回链表。

要求在一趟遍历中完成。

【思路】

两个指针,初始都指向head。

p向下遍历,当遇到第n-1个节点时,q开始向下遍历,这样当p走到最后一个节点,q所指就是要删除的节点。

另需一个pre指针指向q的前一个节点,删除时pre->next=q->next。

【my code】

ListNode *removenode(ListNode* head, int n)
 {
    // int m=0;
     ListNode* pre=head;
     ListNode *p=head;
     ListNode *q=head;
     for(int i=0; p->next!=NULL; i++){
         p=p->next;
         if(i>=n){
             //m++;
             pre=q;
             q=q->next;
         }
     }
    pre->next=q->next;
    delete(q);
    return head;    
 }

【错误】

1.当链表只有一个节点,for循环不执行,pre==null,要单独处理这种情况。

2.当链表有两个节点,{1,2},n=2,for循环执行一次,测试显示结果返回的是{},空链表。WHY?

找到错因:i自增操作在和n比较之后,应该放在比较之前,改为:

for(int i=0; p->next!=NULL; ){
     i++; p
=p->next; if(i>=n){ //m++; pre=q; q=q->next; } }

这样就正确啦!

【other code】

ListNode *removeNthFromEnd(ListNode *head, int n) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (head == NULL)
            return NULL;
            
        ListNode *pPre = NULL;
        ListNode *p = head;
        ListNode *q = head;
        for(int i = 0; i < n - 1; i++)
            q = q->next;
            
        while(q->next)
        {
            pPre = p;
            p = p->next;
            q = q->next;
        }
        
        if (pPre == NULL)
        {
            head = p->next;
            delete p;
        }
        else
        {
            pPre->next = p->next;
            delete p;
        }
        
        return head;
    }

【总结】

1.拿小个数链表,容易出现null的情况来测试。

2.用for循环整合性好,但使用起来有时容易出现错误,因为i的自增运算是在每次循环体最后一句执行,要监视执行时机是否正确。

posted on 2015-04-09 09:56  EmmaLi  阅读(94)  评论(0编辑  收藏  举报

导航