# 82 - 「java」用双指针的方式『删除链表中的重复元素』的详细解题思路
Tags:
- 中等
- 链表
- 双指针
- java
题目链接:
82. 删除排序链表中的重复元素 II
解题思路[双指针]:
因为题目中规定了链表的val值是有序的, 因此可以将题目抽象并简化为: 删除掉链表中值相等的连续子链表, 并返回原链表; 基于上述的简化模型, 可以使用双指针的方式来解题:
- 定义两个指针, 分别为遍历的当前节点c/ 后节点n;
- 每次步进后, 判断n与其后节点(n.next)是否重复, 如果重复, 则需要向后遍历n的后节点, 确认有多少个节点与n重复, 并将n的指针移动到最后一个重复节点;
- 分别将c与n向后步进, 持续进行步骤2的判断;
- 直至遍历到链表的尾部结束遍历;
注意点 [题目中的坑]:
- 每一次的节点重复, 都有可能出现多个连续的重复节点, 所有在判断后, 需要对后节点n向后遍历, 直至出现不重复的节点为止;
- 头结点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%的用户

浙公网安备 33010602011771号