Leetcode 83. 删除排序链表中的重复元素

364 阅读3分钟

Leetcode 83. 删除排序链表中的重复元素

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

1、题目📑

给定一个已排序的链表的头 head删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表

实例1

img

输入:head = [1,1,2]

输出:[1,2]

实例2

img

输入:head = [1,1,2,3,3]

输出:[1,2,3]

限制

  • 链表中节点数目在范围 [0, 300]
  • -100 <= Node.val <= 100
  • 题目数据保证链表已经按升序 排列

2、思路🧠

方法一:单指针

  1. 特判:
    • 如果 head == null 则返回空
    • 如果 head.next == null 头结点下一个节点为空,则返回头结点
  2. 初始化:定义 ListNode cur 指向链表的头部 head
  3. 循环判断:
    • cur.next == null 为循环结束条件
    • cur.valcur.next.val 相等时说明需要去重,将 cur 的下一个指针指向值重复节点的下一个,就能达到去重复的效果
    • cur.valcur.next.val 不相等,即 cur 移动到下一个位置继续循环

方法二:双指针

一般情况下,双指针来解决的链表插入和删除来说是非常的方便,对于数组在某个位置插入和删除非常的繁琐。

  1. 特判:
    • 如果 head == null 则返回空
    • 如果 head.next == null 头结点下一个节点为空,则返回头结点
  2. 初始化:定义 ListNode cur 指向链表的头部 head;定义 ListNode curNext 指向链表的头部 head
  3. 循环判断:
    • 该题目已经是升序排列,所以相同的数据在一起,通过 curNext 来找到下一个不同的数字
    • cur.valcur.next.val 不相等,即找到了不同的数字,则 cur.next = curNext 将该位置的数字的下一个节点指向已经确定位置的 curNext ,紧接着 cur = cur.next 继续后移;
  4. 切记最后一个节点要将它指向 null ,即 cur.next = null

废话少说~~~~~上代码!

3、代码👨‍💻

第一次commit AC

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if(head == null) return null;
        if(head.next == null) return head;
        ListNode cur = head;
        while(cur.next != null) {
            if(cur.val == cur.next.val){
                cur.next = cur.next.next;
            }else {
                cur = cur.next;
            }
            
        }
        return head;
    }
}

时间复杂度:O(N) N代表链表的长度

空间复杂度:O(1)

第二次commit AC

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if(head == null) return null;
        if(head.next == null) return head;
        ListNode cur = head;
        ListNode curNext = cur.next;
        while(curNext != null) {
            if(cur.val != curNext.val) {
                cur.next = curNext;
                cur = cur.next;
            }
            curNext = curNext.next;
        }
        cur.next = null;
        return head;
    }
}

时间复杂度:O(N) N代表链表的长度

空间复杂度:O(1)

image-20220317181652011

4、总结

该题目的最大难度在于是否理解链表的结构,理解双指针,对于初学者来说双指针是非常头疼的问题。

5、链表的相关操作

链接直达🔗

剑指 Offer 18. 删除链表的节点 - 掘金

Leetcode 21. 合并两个有序链表 - 掘金

剑指 Offer 22. 链表中倒数第k个节点 - 掘金

剑指 Offer 24. 反转链表 - 掘金

❤️‍来自专栏《LeetCode基础算法题》欢迎订阅❤️‍

厂长写博客目的初衷很简单,希望大家在学习的过程中少走弯路,多学一些东西,对自己有帮助的留下你的赞赞👍或者关注➕都是对我最大的支持,你的关注和点赞给厂长每天更文的动力。

对文章其中一部分不理解,都可以评论区回复我,我们来一起讨论,共同学习,一起进步!

原题链接:83. 删除排序链表中的重复元素