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

链表算法知识汇总

1.java链表

java中的链表节点都是对象,操作由对象引用来完成,以下是java链表节点的定义:

 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; }}

这些链表节点由JVM自动管理,不需要手动释放内存。

->链表和数组的比较

从以下几个方面:插入与删除性能,查询性能,适用场景

  •  数组在创建时长度就是固定的,如果需要扩容则需要创建新的数组;数组在内存中的分布是连续的。
  • 链表的长度不固定,能够动态的增删节点;链表节点在内存中分布不是连续的,其分配机制取决于操作系统。

  ListNode node = new ListNode();

这行代码的底层实现:

  • 调用new时,JVM向操作系统申请一块内存;
  • 操作系统从进程的堆空间分配一块内存,并返回内存快的地址;
  • JVM将返回的地址存储为对象的引用。

2.java集合之List接口|ArrayList类|LinkedList类

List接口:通常用ArrayList类|LinkedList类两种实现方式

// 使用 List 接口声明,而具体实现为 ArrayList
List<String> list1 = new ArrayList<>();// 使用 List 接口声明,而具体实现为 LinkedList
List<String> list2 = new LinkedList<>();

ArrayList类:底层用动态数组实现。

LinkedList类:底层用双向链表实现。

3.【算法】移除链表元素

题目:leetcode203,移除指定值的节点

思路:为了使删除头节点的操作与删除其他节点的操作统一 => 添加虚拟头节点

代码:

public ListNode removeElements(ListNode head, int val) {// 设置一个虚拟的头结点ListNode dummy = new ListNode();dummy.next = head;ListNode cur = dummy;while (cur.next != null) {if (cur.next.val == val) {cur.next = cur.next.next;} else {cur = cur.next;        }}return dummy.next;
}

注意⚠️:由于要通过下一个节点的值与val比较,cur作为前缀指针,当下一个节点的值被删除后,cur指针不需要移动,这样才能比较下个节点的值。

4.【算法】设计链表

题目:leetcode707,设计一个链表类,实现增删改查

val、next属性不属于链表类,而是新定义节点类。而虚拟头节点dummy、链表长度size才属于链表类,类的定义和初始化如下:

class MyLinkedList {class ListNode {int val;ListNode next;ListNode(int val) {this.val=val;}}//size存储链表元素的个数private int size;//注意这里记录的是虚拟头结点private ListNode head;//初始化链表public MyLinkedList() {this.size = 0;this.head = new ListNode(0);}

另外,由于这个题目是根据索引进行删除、添加等,所以直接使用索引来遍历比"指针"while遍历方便很多,不容易出错。如:

public void deleteAtIndex(int index) {if (index < 0 || index >= size) {return;}//因为有虚拟头节点,所以不用对index=0的情况进行特殊处理ListNode pre = head;for (int i = 0; i < index ; i++) {pre = pre.next;}pre.next = pre.next.next;size--;}

5.【算法】相交链表

题目:给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。如图:

 解题思路:

注意⚠️:该题判断相交节点是判断节点是否是同一个(也就是内存中的地址相同才算同一个节点),而不是判断节点的值!!因此如果能够找到第一个相同的节点c1,那么后面的链表(c2,c3)也都会相同。

所以,可以求出A,B链表的长度,使curA指向curB相同长度的位置,也就是把两个链表尾端对齐,从短链表开头开始找第一个相同节点,比较的方式为"curA==curB"。

 代码如下:

public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {ListNode curA = headA;ListNode curB = headB;int lenA = 0, lenB = 0;while (curA != null) { // 求链表A的长度lenA++;curA = curA.next;}while (curB != null) { // 求链表B的长度lenB++;curB = curB.next;}curA = headA;curB = headB;// 让curA为最长链表的头,lenA为其长度if (lenB > lenA) {//1. swap (lenA, lenB);int tmpLen = lenA;lenA = lenB;lenB = tmpLen;//2. swap (curA, curB);ListNode tmpNode = curA;curA = curB;curB = tmpNode;}// 求长度差int gap = lenA - lenB;// 让curA和curB在同一起点上(末尾位置对齐)while (gap-- > 0) {curA = curA.next;}// 遍历curA 和 curB,遇到相同则直接返回while (curA != null) {if (curA == curB) {return curA;}curA = curA.next;curB = curB.next;}return null;}}

http://www.xdnf.cn/news/19443.html

相关文章:

  • lesson51:CSS全攻略:从基础样式到前沿特性的实战指南
  • 【读论文】量子关联增强双梳光谱技术
  • RabbitMinQ(模拟实现消息队列项目)02
  • 【零碎小知识点 】(四) Java多线程编程深入与实践
  • Spring Cloud ------ Gateway
  • 阿里Qoder怎么样?实测对比TRAE SOLO 和 CodeBuddy IDE
  • 【甲烷数据集】全球逐日无缝隙柱平均干空气甲烷浓度(XCH₄)
  • Solid Explorer文件管理器:功能强大的安卓文件管理器及网盘文件管理器
  • FFMPEG AAC
  • 【MySQL详解】索引、事务、锁、日志
  • 【MySQL基础】MySQL核心操作全解析
  • GPT - 5 技术前瞻与开发者高效接入路径探索​
  • Java-113 深入浅出 MySQL 扩容全攻略:触发条件、迁移方案与性能优化
  • Java实现图像像素化
  • VirtualBox7.2安装步骤
  • RT-DETR网络结构
  • 开源 C# .net mvc 开发(九)websocket--服务器与客户端的实时通信
  • LangChain VectorStores核心:多向量数据库统一交互层与RAG存储中枢
  • 云原生新手入门完整学习指南
  • 14:00面试,15:00就出来了,问的问题过于变态了。。。
  • 【面试场景题】100M网络带宽能不能支撑QPS3000
  • UnderPressure 论文简单解读
  • 【Linux篇章】再续传输层协议UDP :从低可靠到极速传输的协议重生之路,揭秘无连接通信的二次进化密码!
  • 基于STM32的ESP8266连接华为云(MQTT协议)
  • 基于Flask的企业级产品信息管理系统技术实现笔记
  • 从 “能用” 到 “好用”:生成式 AI 落地三大核心痛点与破局路径
  • GPT-5 正式发布:把一个“博士团队”装进手机,AI 新时代开启
  • DevOps篇之通过GitLab CI 流水线实现k8s集群中helm应用发布
  • mysql深度分页
  • C语言:结构体