问题
给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。
例子
思路
-
方法0 O(n) O(n)
-
使用map记住每个元素的个数,由于是递增的,随意只有重复的数字是连续出现的。map<Integer,Integer> 是
-
方法1
非递归,两个指针,方便删除最后一个结点
-
方法2
递归
head和后面结点值不重复,head.next = func(head.next) reutn head;
head和后面结点值重复,将返回 第一个跟head值不一样的结点传入函数 得到的值
代码
//方法0
if(head==null || head.next==null) return head;
Map<Integer,Integer> map = new HashMap<>();
ListNode h=new ListNode(-200);
h.next = head;
ListNode pre = h;
while(head!=null){
map.put(head.val,map.getOrDefault(head.val,0)+1);
head=head.next;
}
//pre去除重复的部分的最后一个节点。
while(pre.next!=null){
if(map.get(pre.next.val)>1)
pre.next = pre.next.next;
else
pre = pre.next;
}
return h.next;
//方法1
class Solution {
public ListNode deleteDuplicates(ListNode head) {
//删除要设置头结点
ListNode h = new ListNode(-200);
h.next = head;
ListNode lastNode = h;
//lastNode为去除重复后的最后一个结点,head为未整理部分的第一个结点
while(head!=null && head.next!=null){
if(head.val!=head.next.val){
lastNode.next=head;
lastNode = lastNode.next;
head = head.next;
}else{
int value = head.val;
while(head!=null && head.val== value) head = head.next;
//head为第一个不与之前重复部分值一样的结点,但也可能跟后面重复
}
}
//后插入,记得如果没有结点了,最后一个结点为null
if(head!=null) lastNode.next = head;
else lastNode.next = null;
return h.next;
}
}
//方法2
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if(head==null || head.next==null) return head;
ListNode firstNode = head;
head = head.next;
if(firstNode.val==head.val){
while(head!=null && firstNode.val==head.val){
head=head.next;
}
//1->1->1->null
//head为null,或者第一个跟firstNode.val不一样的结点。
return deleteDuplicates(head);
}
//else
firstNode.next = deleteDuplicates(firstNode.next);
return firstNode;
}
}