剑指Offer:删除链表中重复的结点Java/Python

1.题目描述

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5

2.算法描述

方法1:迭代

用两个工作指针 p r e , l a s t , p r e 用 来 指 向 已 经 完 成 删 除 过 程 的 结 点 , l a s t 指 向 待 删 除 过 程 结 点 。 \red{pre,last,pre用来指向已经完成删除过程的结点,last指向待删除过程结点。} pre,last,prelast
具体见代码

方法2:递归(似乎有些问题,但是牛客可以AC,不过理解递归思想)

1.如果当前结点和下个结点不同,则同样的方式处理 以 下 一 个 结 点 为 头 结 点 链 表 \red{以下一个结点为头结点链表} 并返回为当前结点作为后继。
2.如果当前接待你和下个结点相同,则跳过这些相同的结点,找到第一个和当前结点不一样结点,同样处理。

3.代码描述

3.1.Java代码

//非递归
/*
 public class ListNode {
    int val;
    ListNode next = null;
    ListNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    public ListNode deleteDuplication(ListNode pHead){
        if(pHead==null || pHead.next == null)
            return pHead;
        ListNode newHead = new ListNode(0);//头节点 方便操作 返回结果的时候 返回newHead.next
        newHead.next = pHead;//头节点接在链表的头部
        //pre用来指向已经完成删除过程的结点,last指向待删除过程结点
        ListNode pre = newHead, last = newHead.next;//两个工作结点
        while(last!=null){
            if(last.next!=null && last.val == last.next.val){//如果当前结点和下个结点一样
                while(last.next!=null && last.val==last.next.val)//找到最后一个相同的结点
                    last = last.next;//跳过相同的结点
                pre.next = last.next;//将最后一个相同的结点(只要一个)链接在pre之后
                last = last.next;//last后移一位
            }
            else{//下一个结点和当前结点不相同,pre和last都后移
                pre = pre.next;
                last = last.next;
            }
        }
        return newHead.next;
    }
}
//递归
/*
 public class ListNode {
    int val;
    ListNode next = null;
    ListNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    public ListNode deleteDuplication(ListNode pHead){
        if(pHead == null || pHead.next == null)//少于2个结点 直接返回
            return pHead;
        ListNode cur = null;
        if(pHead.val != pHead.next.val){//第一个和第个结点不一样
            pHead.next = deleteDuplication(pHead.next);//同样的方式从第2个结点开始删除,然后将结过返回给作为第一个结点的后继
            return pHead;
        }
        else{//第一个和第二个结点值一样
            cur = pHead.next.next;
            while(cur!=null && cur.val==pHead.val)//找到第1个与当前结点值不一样的结点
                //跳过值与当前结点相同的全部结点
                cur = cur.next;
            return deleteDuplication(cur);
        }
    }
}

3.2.Python代码

#非递归
# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def deleteDuplication(self, pHead):
        if pHead==None or pHead.next==None:
            return pHead
        newHead = ListNode(0)
        newHead.next = pHead
        pre = newHead
        last = pre.next
        while last:
            if last.next and last.val==last.next.val:
                while last.next and last.val== last.next.val:
                    last = last.next
                pre.next = last.next
                last = last.next
            else:
                pre = pre.next
                last = last.next
        return newHead.next
#递归
# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def deleteDuplication(self, pHead):
        if pHead==None or pHead.next == None:
            return pHead
        if pHead.val != pHead.next.val:
            pHead.next = self.deleteDuplication(pHead.next)
            return pHead
        else:
            pNode = pHead.next.next
            while pNode and pNode.val == pHead.val:
                pNode = pNode.next
            return self.deleteDuplication(pNode)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值