题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
思路解析
解决这个问题的难点在于如何删除指针指向的那个节点,同时保证指针能够继续使用下去而不是因为删除变成了null。
这里采用新建一个含有首节点的链表。然后将pHead连接上去。达到延后一个的效果来删除重复节点。
- 首先,设置两个指针一个作为快指针,另外一个作为慢指针。快指针在遇到重复的时候,就自己快速的前进,直到到达不是重复的那个值处。(链表是有序的因此不必考虑后面还有重复出现的情况。)如果快指针没有遇到重复的,就移动一步,而慢指针此时也移动一步。此时,慢指针在快指针后面的一个位置。
如1,2,3,3,4,4,5。如当快指针指向2的时候慢指针指向1,快指针指向3的时候,慢指针指向2。同时快指针检测到fast.next是重复的,因此就继续向后面进行。直达fast.val != fast.next.val。此时将slow.next进行调整直接将他指向fast.达到删除的效果。
代码
/*
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 pHead;
ListNode current = new ListNode(-1);
current.next = pHead;
ListNode fast = current.next;
ListNode slow = current;
while(fast!=null){
if(fast.next!=null && fast.next.val == fast.val){
//如果fast指针和它的next值一样,说明是重复值,就将其一直往下遍历
while(fast.next!=null&&fast.next.val == fast.val){
//移动fast到不为重复值出
fast = fast.next;
}
//如果fast到了不为重复值的地方就将其赋给slow进行,slow指针的调整,达到删除重复节点的效果
//值的注意的是此时的cur.next才是第一个重复的,因此需要再移动一步
fast = fast.next;
slow.next = fast;
}else{
//如果fast此时的值和fast.next的值此时不相同,就将其都移动一步
slow = fast;
fast = fast.next;
}
}
return current.next;
}
}