题解 | #删除链表中重复的结点#
删除链表中重复的结点
https://www.nowcoder.com/practice/fc533c45b73a41b0b44ccba763f866ef
方法一:遍历直接删除
因为链表有序,所以才能与相邻元素比较,直接删除!
没有开辟额外的存储空间!
public ListNode deleteDuplication(ListNode pHead) { if(pHead==null)return null; ListNode res =new ListNode(0); res.next = pHead; //用pre和cur来操作res链上的结点! ListNode pre = res; ListNode cur = pHead.next; while(cur!=null){ if(pre.next.val == cur.val){ //必须存储这个值,因为cur将一直变化 int temp = cur.val; while(cur.next!=null&&cur.next.val == temp){ //循环遍历后面重复的部分,一一跳过它们 //注意:cur指针最终停留在最后一个重复节点上,也需要跳过 cur = cur.next; } //pre直接连接到cur的下一个节点去,就删除了这些节点! //若cur的next为空那么pre就是最后一个结点 pre.next = cur.next; if(cur.next==null){ cur = cur.next; }else{ //在我们访问next的时候一定要考虑到它会不会为空! cur = cur.next.next; } }else{ cur = cur.next; pre = pre.next; } } return res.next; }
方法二:哈希表
较为通用的方法,无序链表也可以处理
基本思想为:
- 遍历链表,存储值和出现次数到哈希表
- 遍历链表,一个结点如果出现次数大于1,就删除这个结点
public ListNode deleteDuplication(ListNode pHead) { if(pHead==null)return null; Map<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; } ListNode res = new ListNode(0); //如有可能删除头结点,就必须从res开始 //删除结点就是用其他结点替换掉next里的结点 //只能删除cur的下一个结点,不能删除cur! res.next = pHead; cur = res; while(cur.next!=null){ if(map.get(cur.next.val)!=1){ //cur.next不再指向下一个节点,丢失,成功删除! cur.next = cur.next.next; }else{ //注意这里必须写else! cur = cur.next; } } return res.next; }