【数据结构与算法】之有序链表去重(保留重复元素)

目录

1.问题描述

2.思路讲解

3.Java 代码实现

4.代码解释

5.复杂度分析

6.其它方法

6.1 递归实现

6.2 双指针

7.总结


相关教程:

有序链表去重(不保留重复元素)

数据结构之链表详解

递归详解

1.问题描述

给定一个已排序的单链表的头节点 head,要求去除链表中重复的元素,并返回新的头节点。每个重复元素只保留一个。

图一:

图二:

输入输出示例:

示例 1:
输入:head = [1,1,2]
输出:[1,2]示例 2:
输入:head = [1,1,2,3,3]
输出:[1,2,3]

2.思路讲解

由于链表已经排序,重复的元素必然相邻。我们可以使用一个指针 curr 遍历链表,如果 curr 的下一个节点 curr.next 的值与 curr 的值相同,则将 curr.next 指向 curr.next.next,跳过重复的节点。

3.Java 代码实现

public class RemoveDuplicatesFromSortedList {// 定义链表节点static class ListNode {int val;ListNode next;ListNode(int val) {this.val = val;}}public static ListNode deleteDuplicates(ListNode head) {if (head == null || head.next == null) { // 空链表或只有一个节点,直接返回return head;}ListNode curr = head; // 当前节点指针while (curr.next != null) { // 遍历链表,直到倒数第二个节点if (curr.val == curr.next.val) { // 如果当前节点和下一个节点值相同curr.next = curr.next.next; // 跳过下一个节点,删除重复节点} else {curr = curr.next; // 移动到下一个节点}}return head; // 返回新的头节点}// 测试代码public static void main(String[] args) {// 示例 1ListNode head1 = buildLinkedList(new int[]{1, 1, 2});ListNode result1 = deleteDuplicates(head1);printLinkedList(result1); // 输出:1 2// 示例 2ListNode head2 = buildLinkedList(new int[]{1, 1, 2, 3, 3});ListNode result2 = deleteDuplicates(head2);printLinkedList(result2); // 输出:1 2 3// 示例 3: 空链表ListNode head3 = buildLinkedList(new int[]{});ListNode result3 = deleteDuplicates(head3);printLinkedList(result3); // 输出:// 示例 4: 单个节点ListNode head4 = buildLinkedList(new int[]{1});ListNode result4 = deleteDuplicates(head4);printLinkedList(result4); // 输出:1}// 辅助函数:构建链表private static ListNode buildLinkedList(int[] values) {ListNode dummy = new ListNode(-1);ListNode curr = dummy;for (int val : values) {curr.next = new ListNode(val);curr = curr.next;}return dummy.next;}// 打印链表private static void printLinkedList(ListNode head) {ListNode curr = head;while (curr != null) {System.out.print(curr.val + " ");curr = curr.next;}System.out.println();}
}

4.代码解释

  • ListNode 类定义了链表节点的结构。

  • deleteDuplicates 函数实现了有序链表去重的功能。

  • curr 指针用于遍历链表。

  • while 循环遍历链表,直到倒数第二个节点。

  • if 语句判断当前节点和下一个节点的值是否相同。如果相同,则跳过下一个节点,删除重复节点。

  • else 语句移动 curr 指针到下一个节点。

  • 最后返回新的头节点。

  • 包含了空链表和单节点链表的处理,使其更加健壮。

5.复杂度分析

  • 时间复杂度: O(n),其中 n 是链表的长度。我们最多遍历链表一次。

  • 空间复杂度: O(1),我们只使用了常数个额外变量。

6.其它方法

6.1 递归实现

思路分析:

递归函数负责返回:从当前节点(我)开始,完成去重的链表

  • 若我与 next 重复,返回 next

  • 若我与 next 不重复,返回我,但 next 应当更新

//递归伪代码分析
deleteDuplicates(ListNode p=1) {deleteDuplicates(ListNode p=1) {1.next=deleteDuplicates(ListNode p=2) {2.next=deleteDuplicates(ListNode p=3) {deleteDuplicates(ListNode p=3) {// 只剩一个节点,返回return 3}                }return 2}return 1}
}

代码实现:

public ListNode deleteDuplicates(ListNode p) {if (p == null || p.next == null) {return p;}if(p.val == p.next.val) {return deleteDuplicates(p.next);} else {p.next = deleteDuplicates(p.next);return p;}
}

6.2 双指针实现

思路分析:

-------------------------step1----------------------------
p1   p2
|    |
1 -> 1 -> 2 -> 3 -> 3 -> nullp1.val == p2.val 那么删除 p2,注意 p1 此时保持不变-------------------------step2----------------------------
p1   p2
|    |
1 -> 2 -> 3 -> 3 -> nullp1.val != p2.val 那么 p1,p2 向后移动-------------------------step3----------------------------p1   p2|    |
1 -> 2 -> 3 -> 3 -> nullp1   p2|    |
1 -> 2 -> 3 -> 3 -> null     p1.val == p2.val 那么删除 p2-------------------------step4----------------------------p1   p2|    |
1 -> 2 -> 3 -> null   当 p2 == null 退出循环

代码实现: 

public ListNode deleteDuplicates(ListNode head) {// 链表节点 <  2if (head == null || head.next == null) {return head;}// 链表节点 >= 2ListNode p1 = head;ListNode p2;while ((p2 = p1.next) != null) {if (p1.val == p2.val) {p1.next = p2.next;} else {p1 = p1.next;}}return head;
}

7.总结

本文详细讲解了如何去除有序单链表中的重复元素且每个重复元素保留一个,并提供了 Java 代码实现和详细的解释。希望能帮助各位看官更好地理解和掌握这个算法。下期见,谢谢~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/57200.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java可以做人工智能吗-回答是当然可以

Java在人工智能应用开发中的角色与优势 人工智能主要分为两个部分&#xff1a;一个是做底层的大语言模型的训练&#xff0c;另一个是基于大模型进行业务应用。Java最适合做的就是第二个方面&#xff0c;即基于大模型构建业务应用。由于过去大量的企业级应用都是使用Java开发的…

网络服务请求流程简单理解

网络流程&#xff1a; DNS负责将域名解析为IP地址&#xff0c;ALB可以在多个服务实例之间分配流量&#xff0c;APISIX作为API网关处理更细粒度的流量管理&#xff0c;Service在Kubernetes中为Pod提供稳定的访问入口&#xff0c;而Kubernetes则负责整个应用的部署、扩展和运维。…

Java项目-基于springboot框架的逍遥大药房管理系统项目实战(附源码+文档)

作者&#xff1a;计算机学长阿伟 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、ElementUI等&#xff0c;“文末源码”。 开发运行环境 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBoot、Vue、Mybaits Plus、ELementUI工具&#xff1a;IDEA/…

【UML】一个UML学习的还不错的几个帖子

https://segmentfault.com/a/1190000042775634 寂然解读设计模式 - UML类图&类的六大关系-阿里云开发者社区

最佳简历--JAVA程序员的项目经验如何写

小熊学Java全能学习+面试指南:https://www.javaxiaobear.cn 首先你要明确,你能干什么,包括你自己编写的专业技能,到底会不会,怎么运用到技术上的? 1、你能干什么? 你能干什么,其实就展现你的能力,这是简历中最重要的部分,你需要证明前面说的你会的东东; 这就有点…

【前端】如何制作一个自己的网页(14)

当我们还需要对网页中的内容进行局部样式的修改。这时候&#xff0c;就需要用到HTML中的重要元素&#xff1a;span。 span是一个行内元素&#xff0c;可以对HTML文档中的内容进行局部布局。 如图&#xff0c;我们给标题和段落元素的部分内容设置了各种样式。 接下来&#xff0…

rk3588 opencv 的使用

-------------------------------------------------------------------------------------------------------- 目前是 3588 上无法 直接编译出 C程序。 报错如下&#xff1a; -----------------------------------------------------------------------------------------…

LeetCode 精选 75 回顾

目录 一、数组 / 字符串 1.交替合并字符串 &#xff08;简单&#xff09; 2.字符串的最大公因子 &#xff08;简单&#xff09; 3.拥有最多糖果的孩子&#xff08;简单&#xff09; 4.种花问题&#xff08;简单&#xff09; 5.反转字符串中的元音字母&#xff08;简单&a…

[ComfyUI]Flux:爆火禅语小和尚素材!禅意人生,享受自在

在快节奏的现代生活中&#xff0c;人们越来越渴望一种宁静和放松的状态。而禅意小和尚素材正是这样一种能够带给我们内心宁静和智慧的存在。ComfyUI的Flux框架结合了禅意小和尚素材&#xff0c;为我们提供了一个探索禅意人生的独特方式。 禅意小和尚素材源于佛教文化&#xff…

AJAX—— jQuery 发送 AJAX 请求

1、get 请求 $.get&#xff08;url&#xff0c;[ data ] , [ callback ] , [ type ]&#xff09; url &#xff1a;请求的 URL 地址 data &#xff1a;请求携带的参数 callback &#xff1a;载入成功时回调函数 type &#xff1a;设置返回内容格式&#xff08;xml&#xf…

UniHttp 框架,请求http接口

项目案例下载地址: https://download.csdn.net/download/jinhuding/89902024 1.快速开始 2.1引入依赖 <dependency><groupId>io.github.burukeyou</groupId><artifactId>uniapi-http

leetcode动态规划(十一)-分割等和子集

题目 416.分割等和子集 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集&#xff0c;使得两个子集的元素和相等。 示例 1&#xff1a; 输入&#xff1a;nums [1,5,11,5] 输出&#xff1a;true 解释&#xff1a;数组可以分割成 [1, 5,…

如何进行数据库缩容 | OceanBase应用实践

作者&#xff1a;关炳文&#xff0c;爱可生 DBA 团队成员&#xff0c;负责数据库相关技术支持。 本文详细介绍了OceanBase V3.2版的集群中&#xff0c;面对数据文件缩容的场景的一套缩容方案&#xff0c;作为大家的参考。 缩容场景 某银行运行的一套采用1-1-1架构的OceanBase…

自动驾驶---基于dds/ros的通信中间件

1 背景 DDS&#xff08;数据分发服务&#xff0c;Data Distribution Service&#xff09;和ROS&#xff08;机器人操作系统&#xff0c;Robot Operating System&#xff09;是两种在各自领域内具有重要影响的技术。它们是两种不同的中间件&#xff0c;并且在分布式系统、尤其是…

源代码加密技术的一大新方向!

在当今这个信息爆炸的时代&#xff0c;企业所面临的数据安全挑战日益严峻。传统的文档加密方法已经无法满足日益复杂的安全需求。幸运的是&#xff0c;SDC沙盒加密系统以其革命性的安全理念和先进技术&#xff0c;为企业提供了一个更可靠、更高效的数据保护方案。 传统加密方案…

MySQL-16.DQL-分页查询

一.DQL-分页查询 -- 分页查询 -- 1. 从 起始索引0 开始查询员工数据&#xff0c;每页展示5条记录 select * from tb_emp limit 0,5; -- 2.查询 第1页 员工数据&#xff0c;每页展示5条记录 select * from tb_emp limit 0,5; -- 3.查询 第2页 员工数据&#xff0c;每页展示5条记…

【Kenel】基于 QEMU 的 Linux 内核编译和安装

文章目录 安装虚拟机系统共享目录编译内核卸载内核参考资料 本文主要记录个人做存储系统研究时&#xff0c;在 QEMU 环境下编译和安装 Linux 内核的过程 安装虚拟机系统 之前在 利用 RocksDB ZenFS 测试 ZNS 的环境搭建和使用 给出过借助 VNC 进行图形化安装的步骤&#xff…

利用Pix4D和ArcGIS计算植被盖度

除了水文分析和沟道形态分析之外&#xff0c;在实际工作中还要计算植被盖度&#xff01; 植被盖度&#xff0c;也称为植被覆盖率或植物覆盖度&#xff0c;是指某一地表面积上植物冠层垂直投影面积占该地表面积的比例。它通常以百分比的形式表示&#xff0c;是描述地表植被状况的…

mapbox没有token/token失效,地图闪烁后变空白,报错Error: A valid Mapbox access token is required to use Mapbox GL JS.

目录 mapbox没有token/token失效&#xff0c;地图闪烁后空白&#xff0c;报错Error: A valid Mapbox access token is required to use Mapbox GL JS. 一、问题描述 二、mapbox去除token验证 1、找到mapbox-gl文件夹 2、找到mapbox-gl.js文件 3、找到对应位置并修改 4、清…

uploads-labs靶场刷题记录

Pass-01 尝试上传一句话木马 1.php: <?php eval($_POST[cmd]);?>发现设置了白名单且抓包没有记录&#xff0c;说明在前端进行的拦截&#xff08;可以禁用前端的JS从而绕过拦截&#xff0c;达到直接上传木马的目的&#xff09;。 将一句话木马文件加上.jpg后缀1.php.jp…