删除链表中重复元素

1,395 阅读2分钟

前言

“这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战

这次总结下 链表中重复元素删除的问题

  1. NC25 删除有序链表中重复的元素-I(简单)
  2. NC24 删除有序链表中重复的元素-II(中等)

删除有序链表中重复的元素-I

描述: 删除给出链表中的重复元素(链表中元素从小到大有序),使链表中的所有元素都只出现一次 例如: 给出的链表为1→1→2,返回1→2. 给出的链表为1→1→2→3→3,返回 31→2→3.

思路分析: 已知条件 链表有序, 重复元素最终要求保留一个, 循环 当 当前节点 cur 的 next 不为空时, 判断 cur 的 val 跟 cur.next 的val 是否相等, 相等就跳过 cur.next 让 cur 的 next 指针指向 cur.next 的 next 节点(相当与删除 cur.next 节点), 不相等 就更新 cur 节点

AC 代码:

    public ListNode deleteDuplicates (ListNode head) {
        // write code here
        if(head == null || head.next == null) return head;
        
        ListNode cur = head;
        
        while(cur.next != null){
           if(cur.next.val == cur.val){
               cur.next = cur.next.next;
           }else{
               cur = cur.next;
           }
        }
        return head;
    }

删除有序链表中重复的元素-II

描述 : 给出一个升序排序的链表,删除链表中的所有重复出现的元素,只保留原链表中只出现一次的元素。 例如: 给出的链表为1→2→3→3→4→4→5, 返回1→2→5. 给出的链表为1→1→1→2→3, 返回2→3.

思路分析 : 与上一题不同, 需要删除重复出现的节点, 因此添加一个虚拟的头节点, 避免删除头节点的特殊处理 开始 cur 指向 虚拟的头节点, 然后循环 判断 cur 的后两个相邻节点的值是否相等, 相等的情况下 使用val 变量记录当前需要删除节点的值, 然后向后遍历 将值为val 的节点删除, 不相等的情况下, 说明 cur.next 的节点只出现了一次, 因此 更新 cur 继续循环即可

AC 代码:

    public ListNode deleteDuplicates (ListNode head) {
        // write code here
        if(head == null || head.next == null){
            return head;
        }
        
        ListNode pre = new ListNode(-1);
        pre.next = head;
        
        ListNode cur = pre;
        
        while(cur.next != null && cur.next.next != null){
            if(cur.next.val == cur.next.next.val){
                int val = cur.next.val;
                
                while(cur.next !=null && cur.next.val == val){
                    cur.next = cur.next.next;
                }
            }else{
                cur = cur.next;
            }
        }
        
        return pre.next;
    }