🚩传送门:牛客题目
题目
给出一个升序排序的链表,删除链表中的所有重复出现的元素,只保留原链表中只出现一次的元素。
例如:
给出的链表为 , 返回
给出的链表为 , 返回
数据范围:链表长度 0≤n≤10000,链表中的值满足 ∣val∣≤1000
要求:空间复杂度 O(n),时间复杂度 O(n)
进阶:空间复杂度 O(1),时间复杂度 O(n)
示例1
输入:{1,2,2} 返回值:{1}
示例2
输入:{} 返回值:{}
解题思路:一次遍历
由于给定的链表是排好序的,因此重复的元素在链表中出现的位置是连续的,因此只需要对链表进行一次遍历,就可以删除重复的元素。由于链表的头节点可能会被删除,因此我们需要额外使用一个哑节点(dummy node)指向链表的头节点。
- pre 指向已经处理后未重复部分的末尾结点,
- cur 指向当前判断结点
- next 指向当前判断结点的下一个结点
若 next 和 cur 值相等,则 next 后移
**next=next.next**直至 next=null 或者值不等于 cur 此时将**pre.next=next**删除所有重复的红色部分若 next 和 cur 值不等,则 pre ,cur ,next 依次后移
当遍历完整个链表之后,我们返回链表的的哑节点的下一个节点 dummy.next 即可。
复杂度分析
时间复杂度: ,其中
是链表的长度。
🚩我的代码
public ListNode deleteDuplicates (ListNode head) {// 判空if(head==null)return head;// 初始化ListNode dump=new ListNode(-1,head);ListNode pre=dump;ListNode cur=head;ListNode next=head.next;// 处理直至结尾while(next!=null){// 若相等if(cur.val==next.val){// 直至 next=null 或者值不等于 curwhile(next!=null&&next.val==cur.val)next=next.next;// 舍弃红色的重复部分pre.next=next;cur=next;next=(next==null?null:next.next);}else{ // 不等,指针依次后移pre=cur;cur=next;next=next.next;}}return dump.next;}
官方代码
public ListNode deleteDuplicates(ListNode head) {// 判空if (head == null) return head;// 头结点ListNode dummy = new ListNode(0, head);ListNode cur = dummy;while (cur.next != null && cur.next.next != null) {if (cur.next.val == cur.next.next.val) {int x = cur.next.val;while (cur.next != null && cur.next.val == x) {cur.next = cur.next.next;}} else {cur = cur.next;}}return dummy.next;}
