要求重复的节点一个不保留,题型相似
思路一:头结点,双指针,一个指针指向当前不重复的节点,一个指针作为工作指针,找到当前重复值的最后一个重复值,重点是理解相邻节点值不相等,不代表可以入链,因为该节点可能也是个重复值节点
代码实现:
public class Solution {
public ListNode deleteDuplication(ListNode pHead) {
if(pHead==null || pHead.next==null)
return pHead;
ListNode head=new ListNode(0);
head.next=pHead;
ListNode pre=head;
ListNode last=head.next;
while(last!=null)
{
if(last.next!=null && last.val==last.next.val)//防止空指针异常
{
while(last.next!=null && last.val==last.next.val)//找出该节点的最后一个重复值
{
last=last.next;
}
pre.next=last.next;
last=last.next;
}
else
{
pre=pre.next;
last=last.next;
}
}
return head.next;
}
}
时间O(N)
空间O(1)
总结:思维定式,考虑不全,我只考虑了一个节点不重复的情况,事实是存在多个节点连续重复,题目的示例已给出
思路二:哈希表 +双指针
如果知道哪些值是重复的,遍历链表将其删除,将重复值存入set,遍历链表将set中的值剔除
import java.util.Set;
import java.util.HashSet;
public class Solution {
public ListNode deleteDuplication(ListNode pHead) {
if(pHead==null||pHead.next==null)
return pHead;
Set<Integer> set=new HashSet<>();
ListNode temp=pHead;
while(temp!=null && temp.next!=null)
{
if(temp.val==temp.next.val)
set.add(temp.val);
temp=temp.next;
}
ListNode dummy=new ListNode(-1);
dummy.next=pHead;
ListNode pre=dummy;
ListNode cur=pHead;
while(cur!=null)
{
if(set.contains(cur.val))
{
cur=cur.next;
pre.next=cur;
}
else
{
pre=pre.next;
cur=cur.next;
}
}
return dummy.next;
}
}
时间O(N) 遍历了2次单链表2n
空间O(N)
总结:对链表的操作不够熟练,双指针的使用
一个错排一个小时,set中存储重复值,而不是节点,要不重复节点删不干净