题目链接:JZ76 删除链表中重复的结点
题目描述:在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。
例如,链表 1->2->3->3->4->4->5 处理后为 1->2->5
数据范围:链表长度满足 0
≤
\le
≤
n
n
n
≤
\le
≤ 1000 ,链表中的值满足 1
≤
\le
≤
v
a
l
val
val
≤
\le
≤ 1000
进阶:空间复杂度
O
(
n
)
O(n)
O(n) ,时间复杂度
O
(
n
)
O(n)
O(n)
题目分析:
①双指针法(非递归)。创建一个虚拟节点,用于保存链表的头节点,方便处理第一个节点和第二个节点值相同的情况;last指针一直向后搜索遍历,处理值相等和值不相等两种情况。
时间复杂度O(n) 遍历一次链表
空间复杂度O(1) 开辟一个节点空间
public class Solution {
public ListNode deleteDuplication(ListNode pHead) {
if(pHead==null){
return null;
}
ListNode newHead = new ListNode(-1);
newHead.next = pHead;
ListNode pre = newHead;
//负责一直向后搜索节点
ListNode last = pHead;
while(last!=null){
if(last.next!=null && last.val == last.next.val){
//直到找到最后一个重复节点
while(last.next!=null && last.val==last.next.val){
last = last.next;
}
last = last.next;
pre.next = last;
}else{
pre = last;
last = last.next;
}
}
return newHead.next;
}
}
② 哈希统计。采用hash表存储链表中拥有相同值的结点个数,之后再创建一个虚拟节点,记录链表的头节点,重新遍历链表,判断每一个结点在hash中的值是否为1,如果为1,后移指针,否则去除掉重复的结点。
时间复杂度:O(n) 遍历两次链表
空间复杂度:O(n) 哈希表
import java.util.HashMap;
public class Solution {
//哈希表
public ListNode deleteDuplication(ListNode pHead) {
if(pHead==null){
return null;
}
//遍历链表分别统计具有相同值结点的个数,并存储至hash表中
HashMap<Integer,Integer> map = new HashMap<>();
ListNode cur = pHead;
while(cur!=null){
if(map.containsKey(cur.val)){
map.put(cur.val, (int)map.get(cur.val)+1);
}else{
map.put(cur.val, 1);
}
cur = cur.next;
}
//创建新的头节点,判断每一个结点在hash中的值是否为1
ListNode newHead = new ListNode(-1);
newHead.next = pHead;
cur = newHead;
while(cur.next!=null){
if(map.get(cur.next.val)==1){
cur = cur.next;
}else{
cur.next = cur.next.next;
}
}
return newHead.next;
}
}
总结:承认自己偷懒了,没有写递归的方法,原因是我只能掌握这两种方法。加油吧!不怕难题不会,就怕会题做不对!