链表的基本操作应用2---remove

链表经常需要删除的一些操作。虽然简单但是容易出错。

1,Remove Nth Node From End of List

 

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.

刚开始做的时候,做的比较麻烦的地方。针对的改进。

开始设一个伪头指针,效果更好。ListNode dummy(-1); dummy.next=head;

不用先计算链表的长度,直接两个指针一起走,不用设三个指针,后出发的指针走到删除的结点前一个结点就OK。

下面是经过修改后的代码:

 

 ListNode* removeNthFromEnd(ListNode* head, int n) {
        if(!head||n<=0) return NULL;
        ListNode dummy(-1);
        dummy.next=head;
        ListNode *p1=&dummy,*p2=&dummy;
        for(int i=0;i<n;i++){
            if(p1==NULL) return NULL;//n比链表长度要大
            p1=p1->next;
        }
        while(p1->next!=NULL){
            p1=p1->next;
            p2=p2->next;
        }
        //删除p2前面的结点
        p2->next=p2->next->next;
        return dummy.next;
    }

 

Remove Linked List Elements

Example
Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6
Return: 1 --> 2 --> 3 --> 4 --> 5

注意while的条件,刚开始只写p->next!=NULL;会出错,因为万一p为NULL了就出错。

ListNode* removeElements(ListNode* head, int val) {
        ListNode dummy(-1);
        dummy.next=head;
        if(head=NULL) return NULL;
        ListNode *p1=&dummy,*p2=&dummy;
        while(p1!=NULL&&p1->next!=NULL){//条件中的p1->next很危险,如果p1变为NULL的话。。。加一个条件就好了
            if(p1->next->val==val){
                p2=p1->next->next;
                while(p2!=NULL&&p2->val==val) p2=p2->next;
                p1->next=p2;
            }
            p1=p1->next;
        }
        return dummy.next;
    }


改进一下:只用一个指针。

写的这么乱,我都没想到一次ac。

 

ListNode* removeElements(ListNode* head, int val) {
        ListNode dummy(-1);
        dummy.next=head;
        if(head=NULL) return NULL;
        ListNode *p1=&dummy;
        while(p1&&p1->next){//条件中的p1->next很危险,如果p1变为NULL的话
            if(p1->next->val==val){
                p1->next=p1->next->next;
            }else{
                p1=p1->next;
            }
        }
        return dummy.next;
    }

 

Remove Duplicates from Sorted List II

 

 

For example,
Given 1->2->3->3->4->4->5, return 1->2->5.
Given 1->1->1->2->3, return 2->3.

这次只用一个指针搞定。

ListNode* deleteDuplicates(ListNode* head) {
        if(head==NULL) return NULL;
        if(head->next==NULL) return head;
        ListNode dummy(-1);
        dummy.next=head;
        ListNode *p1=&dummy;
        bool find=false;
        while(p1!=NULL&&p1->next!=NULL){
            if(p1->next->next!=NULL&&p1->next->val==p1->next->next->val){//如果发现有重复现象
                do{
                    p1->next=p1->next->next;
                }while(p1->next->next!=NULL&&p1->next->val==p1->next->next->val);
                p1->next=p1->next->next;//把最后一个重复的删掉
            }else p1=p1->next;
            
        }
        return dummy.next;
    }

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值