标签:实现 dup ret str alt 两种 inf tno 解法
题目描述在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
这个题我分了两种情况,一种是头结点不用删除(即头结点和后面结点的值不相等),另一种是头结点需要删除(即头结点和后面结点的值相等)。如果头结点删除了就要重新找新的头结点。
对于这个题的解法,我定义了三个指针 n1、n2、n3。n1 的初始值设为 null,n2 的初始值设为头结点,n3 的初始值设为头结点的下一个结点。n1 的作用是为了删除链表重复的结点,n2 和 n3 负责找到要删除的结点。
头结点不需要删除的情况:
①
n2、n3 的值不相等,n1、n2 和 n3 都往后移一个。
②
此时 n2 和 n3 的值相等,n1、n2 不动,n3 往后移动,直到 n3 的值和 n2 的值不相等。
③
n3 走到了与 n2 值不相等的结点,下一步就直接将 n2 走到 n3 的位置。
④
n2 走到了 n3 的位置,将 n1 的下一个结点指向新的 n2 的位置,就将中间重复的结点删除了。
⑤
n3 继续往前走,依次列推,直到将链表遍历完。
头结点需要删除的情况:
①
n2、n3 的值相等,n3 往后走直到结点的值与 n2 不相等。
②
走到这一步,链表前两个相等的结点已经被删除了,此时头结点也被删除了,所以就要更新 pHead 的值(这道题我是直接用 pHead 保存的头结点)。
③
n3 往后移一个,走到这里相当于一次循环已经结束了,后面的遍历就和前面的一样,直到链表遍历完。
public ListNode deleteDuplication(ListNode pHead) {
if (pHead == null) {
return null;
}
ListNode n1 = null;
ListNode n2 = pHead;
ListNode n3 = n2.next;
while (n3 != null) {
if (n2.val != n3.val) {
//n2,n3不相等时,n1,n2,n3都往后移动
n1 = n2;
n2 = n3;
n3 = n3.next;
} else {
//[n2,n3)是重复区间,注意区间的范围是是左闭右开
while (n3 != null && n2.val == n3.val) {
n3 = n3.next;
}
//while循环结束时,n3的已经走到了和n2不相等的位置上,要删除掉重复的数字就直接让n2走到n3上
n2 = n3;
if (n1 != null) {
//将 n1 的下一个结点指向 n2,就把中间重复的数字删除了
n1.next = n2;
} else {
//如果链表的第一位和第二位都相等,头结点也会被删除,n1就变成null了,所以这里就是更新头结点
pHead = n2;
}
if (n3 != null) {
n3 = n3.next;
}
}
}
return pHead;
}
标签:实现 dup ret str alt 两种 inf tno 解法
原文地址:https://blog.51cto.com/14298563/2506151