# 82 - 「java」用双指针的方式『删除链表中的重复元素』的详细解题思路

Tags:

  • 中等
  • 链表
  • 双指针
  • java

题目链接:

82. 删除排序链表中的重复元素 II

解题思路[双指针]:

因为题目中规定了链表的val值是有序的, 因此可以将题目抽象并简化为: 删除掉链表中值相等的连续子链表, 并返回原链表; 基于上述的简化模型, 可以使用双指针的方式来解题:

  1. 定义两个指针, 分别为遍历的当前节点c/ 后节点n;
  2. 每次步进后, 判断n与其后节点(n.next)是否重复, 如果重复, 则需要向后遍历n的后节点, 确认有多少个节点与n重复, 并将n的指针移动到最后一个重复节点;
  3. 分别将c与n向后步进, 持续进行步骤2的判断;
  4. 直至遍历到链表的尾部结束遍历;

注意点 [题目中的坑]:

  1. 每一次的节点重复, 都有可能出现多个连续的重复节点, 所有在判断后, 需要对后节点n向后遍历, 直至出现不重复的节点为止;
  2. 头结点head也有可能直接与第二个节点重复, 则删除以后, 头结点head的指针也有可能会改变, 所以我们需要自定义一个pre节点, 用pre.next=head, 来标定head, 使得head也能够移动

实现代码[双指针]:

class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if(head == null ||  head.next == null){
            return head;
        }
        //双指针
        ListNode pre = new ListNode();  //自定义头结点(防止头结点重复的场景)
        pre.next = head;

        ListNode c = pre;    //当前节点
        ListNode n = pre.next;   //后节点
        while(n != null){
            //后节点与下一个节点重复
            if(n.next!= null && n.val == n.next.val){
                while(n.next != null && c.next.val == n.next.val){  //此处需要用循环(可能会有超过2个重复的节点, 需要一直向前遍历)
                    n = n.next; //next节点步进到最后一个与当前节点重复的节点
                }
                n = n.next; //next节点再后移一位
                c.next = n; //重定义c的后节点
                continue;
            }
            c = n;  //当前节点步进一位
            n = n.next; //后节点步进一位
        }
        return pre.next;    //不直接返回head是为了防止原头结点就开始重复.
    }
}

提交结果[20210702]:

执行用时:1 ms, 在所有 Java 提交中击败了74.34%的用户
内存消耗:37.8 MB, 在所有 Java 提交中击败了63.26%的用户
posted @ 2023-03-15 19:54  zhiyuanZAG  阅读(31)  评论(0)    收藏  举报