题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
解题思路
- 设置3个结点,root指向头节点,post指向循环结点之后的第一个结点,pre指向循环结点的第一个结点;
- isRepeated标志位标识是否重复;
- 如果post值等于pre值,删除post结点,post向后移一步,isRepeated设为true;
- 如果post值不等于pre值,根据isRepeated判断此时post指向的结点是否是重复结点,如果不是,post和pre都向后移一步,如果是重复结点,则判断该结点是不是头结点,如果是头节点,则更新root和pHead为当前结点,pre指向当前结点,post后移一位,如果不是头节点,由于此时pre指向的是重复的结点,需要把pre删掉,则更新root到pre的前一个结点,把pre结点删除。
我的代码
/*
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, post = pHead.next, root = pHead;
boolean isRepeated = false;
while(post != null){
if(pre.val == post.val){
isRepeated = true;
post = post.next;
pre.next = post;
} else {
if(isRepeated){
// 删除当前节点 pre指回前一个结点
if(root.val == pre.val){
pre = post;
root = post;
pHead = post;
post = post.next;
} else {
while(root.next != pre){
root = root.next;
}
pre = root;
pre.next = post;
post = post.next;
pre = pre.next;
}
isRepeated = false;
} else {
post = post.next;
pre = pre.next;
}
}
}
if(isRepeated){
if(pre == pHead) return null;
while(root.next != pre){
root = root.next;
}
pre = root;
pre.next = post;
}
return pHead;
}
}
别人非常优秀的递归代码
public class Solution {
public ListNode deleteDuplication(ListNode pHead) {
if (pHead == null || pHead.next == null) { // 只有0个或1个结点,则返回
return pHead;
}
if (pHead.val == pHead.next.val) { // 当前结点是重复结点
ListNode pNode = pHead.next;
while (pNode != null && pNode.val == pHead.val) {
// 跳过值与当前结点相同的全部结点,找到第一个与当前结点不同的结点
pNode = pNode.next;
}
return deleteDuplication(pNode); // 从第一个与当前结点不同的结点开始递归
} else { // 当前结点不是重复结点
pHead.next = deleteDuplication(pHead.next); // 保留当前结点,从下一个结点开始递归
return pHead;
}
}
}