剑指 Offer
如果需要删除链表中的一个已知结点时,需不需要通过链表遍历找到该结点的前一个结点然后将前一个结点指向该结点的下一个结点?
不需要,可以将该结点的下一个结点的值复制给该结点,然后该结点的 next 下下个结点。 不过需要考虑 3 种情况:1.链表只有一个结点(头指针需要赋值为NULL) 2.该结点是尾节点(需要遍历找到该结点的前一个结点) 3.链表中的结点。 平均复杂度((N-1)* O(1)+O(N))/N = O(1)。
题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表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(pHead==null){
return null;
}
ListNode pre=pHead;
ListNode current=pHead.next;
//判断是否需要删除
boolean isDelete;
while(current!=null){
isDelete=false;
while(current!=null&&pre.val==current.val){
current=current.next;
isDelete=true;
}
if(isDelete){
//删除改删掉的重复结点
pHead=delete(pHead,pre,current);
if(current!=null){
//因为删除后 pre 和 current指向同一个结点
current=current.next;
}
}else{
pre=current;
current=current.next;
}
}
return pHead;
}
public ListNode delete(ListNode pHead,ListNode pre,ListNode current){
boolean isHead=false;
//判断头和pre是否相等
if(pHead==pre){
isHead=true;
}
//到链表尾部
if(current==null){
if(isHead){
//只有一个结点
pHead=null;
}else{
ListNode temp=pHead;
while (temp.next!=pre){
temp=temp.next;
}
temp.next=null;
}
}else{
pre.val=current.val;
pre.next=current.next;
if(isHead){
//删除的头结点重复元素
pHead=pre;
}
}
return pHead;
}
}