题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5。
解题思路
先新建一个头节点,然后向后查找值相同的结点,重复查找后删除
代码实现
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ListNode deleteDuplication(ListNode pHead) {
if (null == pHead) {
return null;
}
// 新建一个结点,防止头结点被删除
ListNode firstNode = new ListNode(-1);
firstNode.next = pHead;
// 记录前驱结点
ListNode preHead = firstNode;
// 记录当前遍历结点
ListNode p = pHead;
while ((null != p) && (null != p.next)) {
// 若结点值出现重复
if (p.val == p.next.val) {
int val = p.val;
// 删除重复结点
while ((null != p) && (val == p.val)) {
p = p.next;
}
// 删除重复结点后,进行链接
preHead.next = p;
} else {
// 结点不重复,后移
preHead = p;
p = p.next;
}
}
return firstNode.next;
}
}
注意
while ((null != p) && (val == p.val)) {
p = p.next;
}
其中,条件中的 (null != p) && (val == p.val) 不可以颠倒,否则会引发空指针异常。
因为,此时当循环到达p指向链表的末尾时,此时p.next为空,则p=p.next,p为null。若先判断 (val == p.val) 会因p=null,使得读取p.val时发生空指针异常;若先判断 (null != p) ,则已不再满足循环条件,由“&&”的截断机制,不再继续执行判断。