版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zxm1306192988/article/details/82012564
题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
题解:
方法一:循环
要用一个指针 p 指向当前处理的结点,指针temp 向前移动,直到移动到不相同的结点。
由于需要把相同的结点都删除,所以需要用一个指针behind指向他前面的结点,并用flag 判断是否出现相同的结点,如果出现,则behind 的next 直接指向 temp(如果从头结点重复,behind是null,则pHead直接指向temp ) 。即可把中间重复部分的结点都删除。如果没有重复的部分,behind直接移到 p.
注意每次while循环时要判断 p 是否为null。
public class Solution {
public ListNode deleteDuplication(ListNode pHead) {
if (pHead == null || pHead.next == null) {
return pHead;
}
ListNode p = pHead;// 指向当前结点
ListNode behind = null; // 指向上一个结点
while (p != null && p.next != null) {
ListNode temp = p.next; //向前移动的指针
boolean flag = false; //表示是否有重复的
while (temp != null && temp.val == p.val) {//如果相等,就继续向前移动
temp = temp.next;
flag = true;
}
if (behind == null && flag == true) { //如果有重复的,且是头结点,则pHead直接指向temp
pHead = temp;
} else if (behind != null && flag == true) { //如果 不是从头结点开始的,且有重复的,behind的next指向temp,即把中间重复的都去掉
behind.next = temp;
} else { //如果没有重复的,behind指向p
behind = p;
}
p = temp;//p 移动 temp
}
return pHead;
}
}
方法二:递归
分两种情况讨论:
- 头结点是重复结点,返回非重复结点的递归结果。
- 头结点不是重复结点,返回头结点,头结点的next指向 下个结点的递归结果。
递归退出条件,只有0个或1个几点,不可能有重复结点了,则返回。
public class Solution {
public ListNode deleteDuplication(ListNode pHead) {
if (pHead == null || pHead.next == null) {
return pHead;
}
ListNode next = pHead.next;
if (pHead.val == next.val) {// 如果从头开始就有重复的,则前面重复的都去掉,返回从非重复结点的递归计算结果
while (next != null && pHead.val == next.val) {
next = next.next;
}
return deleteDuplication(next);
} else {// 如果头结点不是重复结点,则头结点的next指向,递归结果,还是返回头结点
pHead.next = deleteDuplication(pHead.next);
return pHead;
}
}
}