[路飞]_leetcode-82-删除排序链表中的重复元素 II

简介: leetcode-82-删除排序链表中的重复元素 II

网络异常,图片无法展示
|


「这是我参与11月更文挑战的第23天,活动详情查看:2021最后一次更文挑战


[题目地址][B站地址]


存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中 没有重复出现 **的数字。


返回同样按升序排列的结果链表。


示例 1:


网络异常,图片无法展示
|


输入: head = [1,2,3,3,4,4,5]
输出: [1,2,5]
复制代码


示例 2:


网络异常,图片无法展示
|


输入: head = [1,1,1,2,3]
输出: [2,3]
复制代码


提示:


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


本题和 83. 删除排序链表中的重复元素 相似,只是在 83 题的基础上加了那么一丢丢🤏难度


本题要我们删除有序链表中的重复元素


也就是说当出现值相同的元素出现多次的情况,要把这些元素都删除掉


又因为题目给出的链表是有序的,所以值相同的元素一定是连在一起的


所以我们可以在遍历链表的过程中判断是否出现了重复元素


如果出现了重复元素,则把这些重复元素删除,直到链表末尾即可


那在链表中,删除一个节点如何操作呢?


例如:有链表 1=>2=>3=>null,此时如果想要删除链表中 2 号节点,则只需要将链表中 1 号节点的 next 的指针指向 3 号节点,即可达到在该链表中删除 2 号节点的效果


有了以上基础,我们来看下本题如何求解


解题思路如下:


  1. 首先特殊判断链表为空或者只有一个节点,直接返回原链表
  2. 因为头节点也可能被删除,所以创建虚拟头节点 vhead 方便最后返回结果
  3. 初始化 pre 指针指向虚拟头节点 vhead
  4. 初始化 cur 指针指向头节点 head
  5. 初始化 next 指针指向 head.next
  6. 遍历链表,判断 next 指针指向节点值是否等于 cur 指针指向节点值,如果相等,说明出现了重复元素,此时让 next 指针向后走,直到找到第一个不等于 cur 的节点
  7. pre.next 指向 next,达到删除 cur 以及重复元素的效果
  8. 更新 cur = nextnext = next?next.next:null
  9. 链表遍历完成后,返回 vhead.next 即可


整体过程如下:


网络异常,图片无法展示
|


代码如下:


var deleteDuplicates = function(head) {
  // 特判 链表为空或者只有一个节点,直接返回原链表
  if(head === null || head.next === null) return head;
  // 因为头节点也可能被删除,创建虚拟头节点方便操作
  const vhead = new ListNode(0);
  vhead.next = head;
  // 定义三个指针
  // 重复元素的前一个节点
  let pre = vhead,
  // 重复元素
  cur = head,
  // 重复元素的后一个节点
  next = head.next,
  // 当前是否找到了重复元素
  tag = false;
  // 遍历链表
  while(next){
    // 当 next 不为空并且next的值等于 cur 的值,一直向后走
    while(next && next.val === cur.val){
      // 标记当前 cur 是重复元素
      tag = true;
      next = next.next;
    }
    // 如果 tag 为 true 说明当前 cur 为重复元素,next 为第一个不等于 cur 的元素
    if(tag){
      pre.next = next;
      cur = next;
      next = next?next.next:null;
      tag = false;
    }else{
      // 否则一起向后走,遍历链表
      pre = pre.next;
      cur = cur.next;
      next = next?next.next:null;
    }
  }
  return vhead.next;
};
复制代码


至此我们就完成了 leetcode-82-删除排序链表中的重复元素 II


如有任何问题或建议,欢迎留言讨论!

相关文章
【力扣】-- 移除链表元素
【力扣】-- 移除链表元素
256 1
|
机器学习/深度学习 存储 算法
【LeetCode 热题100】347:前 K 个高频元素(详细解析)(Go语言版)
这篇文章详细解析了力扣热题 347——前 K 个高频元素的三种解法:哈希表+小顶堆、哈希表+快速排序和哈希表+桶排序。每种方法都附有清晰的思路讲解和 Go 语言代码实现。小顶堆方法时间复杂度为 O(n log k),适合处理大规模数据;快速排序方法时间复杂度为 O(n log n),适用于数据量较小的场景;桶排序方法在特定条件下能达到线性时间复杂度 O(n)。文章通过对比分析,帮助读者根据实际需求选择最优解法,并提供了完整的代码示例,是一篇非常实用的算法学习资料。
853 90
【LeetCode 27】347.前k个高频元素
【LeetCode 27】347.前k个高频元素
211 0
|
算法 Go
【LeetCode 热题100】23:合并 K 个升序链表(详细解析)(Go语言版)
本文详细解析了 LeetCode 热题 23——合并 K 个升序链表的两种解法:优先队列(最小堆)和分治合并。题目要求将多个已排序链表合并为一个升序链表。最小堆方法通过维护节点优先级快速选择最小值,;分治合并则采用归并思想两两合并链表。文章提供了 Go 语言实现代码,并对比分析两种方法的适用场景,帮助读者深入理解链表操作与算法设计。
526 10
203. 移除链表元素,707.设计链表,206. 反转链表
链表是数据结构中的重要概念,包含单链表、双链表和循环链表。单链表每个节点存储数据与下一节点指针;双链表增加上一节点指针;循环链表首尾相连。 **例题解析:** 1. **203. 移除链表元素**:通过遍历链表删除指定值节点,注意处理头节点特殊情况。 2. **707. 设计链表**:实现链表的增删查操作,需理解指针操作逻辑,避免直接修改目标节点。 3. **206. 反转链表**:采用双指针或递归方法改变节点指向,完成链表反转。 以上题目涵盖链表核心操作,掌握后可灵活应对相关问题。
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
461 6
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
242 6
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
558 2
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
469 4
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
504 1