剑指Off打卡day36—— ACWing29. 删除链表中重复的节点
Posted Johnny*
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指Off打卡day36—— ACWing29. 删除链表中重复的节点相关的知识,希望对你有一定的参考价值。
【题目描述】
29. 删除链表中重复的节点
【思路】
有误代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteDuplication(ListNode head) {
if(head == null) return head;
//虚拟头结点
ListNode h = new ListNode(-1);
h.next = head;
while(h.next != null){
//只要下一个节点非空(即该节点非最后一个节点)且下一个节点值与当前节点值不相等
while(h.next !=null && h.next.val != h.val )h = h.next;
if(h.next != null){ //找到第一个重复的点 h.next
ListNode p = h;
//寻找最后一个重复的位置p
while(p.next != null && p.next.val == p.val) p = p.next;
//删除指针h到指针p这段 [h,p] 在没有前驱的情况下要删除当前节点
//先将p.next.val复制给h.val
h.val = (p.next== null ? null:p.next.val) ;
//再修改指针
h.next = (p.next == null? null: p.next.next);
}
}
return head;
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
/*
注意是重复的节点全部删除:无需保留
*/
class Solution {
public void toString(ListNode h){
while(h !=null ){
System.out.print(h.val+" ");
h = h.next;
}
System.out.println();
}
public ListNode deleteDuplication(ListNode head) {
ListNode cur = head;
ListNode next = head.next;
while( next != null){
if( next != null && cur.val == next.val){
//cur指针不动 next指针++,一直到不相同的节点或者到空节点
while( next != null && cur.val == next.val ){
next = next.next;
}
if( next != null){//如果不为null 则next 指向不同于cur的节点
//找到重复区间[cur,next)
//没有前驱节点的修改方法
cur.val = next.val;
cur.next = next.next;//注意是next.next 不是next 因为next节点的值已经复制到cur节点上了
}else{
cur.next = null;
cur = next;
}
//toString(cur);
}
toString(cur);
}
return head;
}
}
正解
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
/**
由于可能会删除头结点,所以引入虚拟节点
方便统一逻辑
*/
class Solution {
public ListNode deleteDuplication(ListNode head) {
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode p = dummy;
//p指向上一段的最后一个元素 q指向当前段的第一个元素
//每次扫描元素相同的一段
while( p.next != null){
ListNode q = p.next;
// 注意不能写成:while( q.next != null && q.val == q.next.val ) q = q.next;
while( q != null && p.next.val == q.val ) q = q.next;
if( p.next.next == q) p = p.next; //该段的元素个数为1
else p.next = q; //将(p,q)区间删除 只需 q.next = q
}
return dummy.next;
}
}
以上是关于剑指Off打卡day36—— ACWing29. 删除链表中重复的节点的主要内容,如果未能解决你的问题,请参考以下文章
剑指Offer打卡day42—— Acwing 62. 丑数
剑指Offer打卡day42——AcWing 77. 翻转单词顺序
剑指Offer打卡day42—— ACWing 81. 扑克牌的顺子
剑指Offer打卡day43—— Acwing 86. 构建乘积数组