当前位置: 首页 > news >正文

【LeetCode】82. 删除排序排序链表中的重复元素 II

【LeetCode】82. 删除排序排序链表中的重复元素 II

题目

【LeetCode】82. 删除排序排序链表中的重复元素 II

给定一个已排序的链表的头 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
题目数据保证链表已经按升序 排列

解题思路

核心要点:

  • 链表已排序,因此重复元素必然连续出现
  • 需要删除所有重复的节点,而不仅仅是去重保留一个
  • 可能需要删除头节点,因此使用虚拟头节点会更方便

有效的解法是一次遍历法

  1. 创建虚拟头节点(dummy node),其next指向原链表头节点,便于处理头节点可能被删除的情况
  2. 使用prev指针指向当前确定不重复的节点,curr指针用于遍历链表
  3. 当curr和curr.next的值相同时,说明出现重复,记录当前重复值,然后将curr移动到最后一个重复节点的下一个位置
  4. 如果没有出现重复,则将prev移动到curr位置,curr继续后移
  5. 遍历结束后,返回虚拟头节点的next

这种方法只需一次遍历,时间复杂度为O(n)。

代码实现

class ListNode {int val;ListNode next;ListNode() {}ListNode(int val) { this.val = val; }ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}public class RemoveDuplicates {public ListNode deleteDuplicates(ListNode head) {// 创建虚拟头节点,处理头节点可能被删除的情况ListNode dummy = new ListNode(0);dummy.next = head;// prev指向当前确定不重复的节点ListNode prev = dummy;// curr用于遍历链表ListNode curr = head;while (curr != null) {// 标记是否有重复boolean hasDuplicate = false;// 找到当前重复元素的最后一个节点while (curr.next != null && curr.val == curr.next.val) {hasDuplicate = true;curr = curr.next;}if (hasDuplicate) {// 如果有重复,跳过所有重复节点prev.next = curr.next;} else {// 如果没有重复,prev移动到当前节点prev = curr;}// curr继续后移curr = curr.next;}return dummy.next;}// 测试示例public static void main(String[] args) {RemoveDuplicates solution = new RemoveDuplicates();// 示例1: 1->2->3->3->4->4->5ListNode head1 = new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(3, new ListNode(4, new ListNode(4, new ListNode(5)))))));ListNode result1 = solution.deleteDuplicates(head1);printList(result1);  // 输出:1->2->5->null// 示例2: 1->1->1->2->3ListNode head2 = new ListNode(1, new ListNode(1, new ListNode(1, new ListNode(2, new ListNode(3)))));ListNode result2 = solution.deleteDuplicates(head2);printList(result2);  // 输出:2->3->null}// 打印链表,格式为[val1, val2, ...]private static void printList(ListNode head) {StringBuilder sb = new StringBuilder();sb.append("[");ListNode curr = head;while (curr != null) {sb.append(curr.val);if (curr.next != null) {sb.append(",");}curr = curr.next;}sb.append("]");System.out.println(sb.toString());}
}

复杂度分析

  • 时间复杂度:O(n),其中n是链表的长度。我们只需要遍历一次链表。
  • 空间复杂度:O(1),只使用了常数个额外变量。

关键要点

  • 虚拟头节点的使用:简化了头节点可能被删除的情况处理
  • 双指针技巧:prev指针跟踪已确认不重复的节点,curr指针负责遍历和发现重复节点
  • 一次遍历即可完成,效率高
  • 处理重复节点的逻辑:当发现重复时,将prev的next直接指向最后一个重复节点的下一个位置,从而删除所有重复节点
http://www.dtcms.com/a/398716.html

相关文章:

  • 如何设计一个企业级消息推送系统架构?
  • 使用IOT-Tree消息流实现实时数据同步:标签实时数据--关系数据库表
  • 国外做网站公司能赚钱备案网站多长时间
  • 淘宝网站是谁做的好wordpress 分类信息主题
  • Scikit-learn Python机器学习 - 回归分析算法 - 岭回归 (Ridge Regression)
  • 【mysql】内部技术架构
  • 马来西亚股票数据API对接文档
  • 【C++实战㉟】解锁C++面向对象设计:里氏替换原则实战指南
  • 邮件系统的未来趋势:技术革新与智能化的未来
  • 解决MySQL的sql_mode=only_full_group_by错误提示
  • phpcms 网站名称标签建设政协网站的意义
  • 【langgraph】docker镜像查看langraph-api相关版本
  • Datawhale25年9月组队学习:llm-preview+Task3:提示词工程
  • RunnableLambda
  • 记录一次windows资源管理器崩溃,任务栏无法打开任何软件
  • 【开题答辩过程】以《基于SSM框架的植物园管理系统的实现与设计》为例,不会开题答辩的可以进来看看
  • 浅拷贝与深拷贝的区别?
  • python免费自学网站做网站的作品思路及步骤
  • PyTorch 构建神经网络
  • 人工智能医疗系统灰度上线与评估:技术框架实践分析python版(下)
  • 网站推广费用一般多少钱设计工作室logo
  • Eclipse配置tomcat+创建javaweb项目
  • 做国际网站找阿里西安市今天发生的重大新闻
  • 深圳工程建设交易服务中心网站郑州做网站zzmshl
  • Flink-SQL通过过滤-解析-去重-聚合计算写入到MySQL表
  • 公司网站建设记哪个科目网站建设对企业的要求
  • 汕头网页设计制作金华seo扣费
  • Vue电商数据分析大屏开发
  • 【开题答辩全过程】以 bilibili排行榜的数据分析与可视化为例,包含答辩的问题和答案
  • AI性能对决!蓝耘MaaS平台在2025大模型测评中如何脱颖而出