LeetCode [82] 删除排序链表中的重复元素 II

本文介绍了一种算法,用于删除排序链表中的重复元素,并提供了两种实现方法:一种是在遍历过程中直接删除重复元素;另一种是在第一次遍历时标记重复元素,第二次遍历再删除。这两种方法各有优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LeetCode [82] 删除排序链表中的重复元素 II

题目描述

给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。

示例 1:

输入: 1->2->3->3->4->4->5
输出: 1->2->5
示例 2:

输入: 1->1->1->2->3
输出: 2->3

题目分析

删除链表和删除数组不同,麻烦的就是各个数之间的连接性。遍历链表就是用while循环。但是思路其实还是比较好想的。复制一下当前的值,往后查找有多少的相同的,跳过相同的连接后面的链表。

源码

/**
* Definition for singly-linked list.
* public class ListNode {
*     int val;
*     ListNode next;
*     ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteDuplicates(ListNode head) {
    if(head==null) return null;
    ListNode dumhead=new ListNode(-1);
    //创这个是为了保证及时head开始就有重复的,那我也能删除
    dumhead.next=head;
    ListNode cur=head;
    ListNode pre=dumhead;
    while(cur!=null&&cur.next!=null){
        if(cur.val==cur.next.val){
            int val=cur.val;
            while(cur!=null&&cur.val==val){
                cur=cur.next;
            }
            pre.next=cur;
        }else{
            pre=cur;
            cur=cur.next;
        }
    }
    return dumhead.next;
}
}

改进

还有一个方法其实差不多,但是比较巧妙,就是边循环边删除太难理解了,那么能不能我遍历完了再删除。其实是可以的,在遍历的过程中,我可以把遇到相同的数值赋值给-128(Integer范围是-128~127),然后再遍历一遍,把值为-128的删除。

改进代码

class Solution {
public ListNode deleteDuplicates(ListNode head) {
    //判断链表是否为空
    if(head == null) return null;
    //新建一个虚拟头节点
    ListNode dummy = new ListNode(-1);
    //把虚拟头节点和链表连在一起
    dummy.next = head;
    ListNode current = head;
    ListNode pNode;
    //遍历寻找相同的值
    while(current.next != null){
        int val = current.val;
        pNode = current.next;
        //从非current指向的节点开始遍历这个val在其他节点是不是有
        while(pNode != null){
            //如果有,把两个相同的值赋-128,最后在链表中直接删除-128的值
            if(val == pNode.val){
                pNode.val = current.val = -128;
            }
            pNode = pNode.next;
        }
        //把current指针移到下一个节点,取值和其他节点进行对比
        current = current.next;
    }
    
    //这里就是遍历操作删除值为-128的节点
    ListNode c = dummy;
    while((pNode = c.next)!= null){
        if(pNode.val==-128){
            c.next = pNode.next;
        }else{
            c = pNode;
        }
    }        
    return dummy.next;
}
}

分析

第一个时间复杂度为O(n^2)
第二个就是O(n^2),空间的复杂度第一个稍微高一点

难点

难点其实是删除链表而不是找相同的,做链表题最烦的也就是删除插入,因为要考虑连接性。而且对头和尾的处理都必须小心,一不小心就会出错。

小结

删除链表最好就要创建一个虚链表保存头,这样就不会有遗漏了,最后返回只要返回虚链表后面的就完成了。
[1]https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/submissions/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值