算法学习 (门徒计划)1-1 链表 学习笔记
前言
3月4日,开课吧门徒计划算法课第一讲学习笔记。
本课讲链表。
课题为:
1-1 链表以及经典问题
链表
链表概念简述
通常链表指单向链表,单向链表每一个最小单元包含2个参数,一个是存储的内容,另一个是指向下一个节点的内容。
也就是说,链表中的任何一个节点都能获取到其下一个节点(除非没有下一个节点)或者这个储存的内容。
java 方式链表节点举例:
public class ListNode {
int val;
ListNode next = null;
}
每个对象存储了一个内容和下一个对象。
链表特性
查询动作时间复杂度 n
由于链表是通过指针域的方式实现排布,因此当需要查询一个节点时,需要遍历该节点前所有节点,所以时间复杂度为o(n)。
插入和删除时间复杂度 1
当需要插入或者删除某个节点时,只需要对这个节点前后的指向关系进行修改,因此时间复杂度为o(1)。
链表场景应用场景
场景一:操作系统的动态内存分配
假设原始内存区域为10GB,现在使用malloc函数(一个动态分配内存的函数,这部分内存需要手动释放)分配了2GB内存,那么剩下的8GB内存就需要操作系统去进行维护。
而有一种操作系统维护内存的方式(openVPN中有一种基于链表的内存管理方案)就是通过将不同的剩余内存碎片穿成链表进行维护。
场景二:LRU缓存淘汰算法
LRU(Least Recently Used)(意思为近期最少使用)
举例:
设备间存在速度差异,可以通过将使用频率高的数据存放在高速设备上,来实现更高效率的调用。
其实现的方法为当容量到达上限时,删除(或转移)最少使用的,为新的数据留出空间。
经典问题
链表的反转
要求在不进行修改存储值的情况下,通过修改链表各个单元对于下一个单元的指向关系来翻转链表的元素顺序。
通用案例
要求将某个链表从第n个元素开始翻转k个长度
如图,n为3,k为3
思考解决方案:
首先除翻转段外,其余部分应保持不变,因此链表被分为3份,
- 翻转区块之前的一份:
顺序不变,最终末尾指向翻转区域的首位; - 翻转区块的一份:改变顺序,最终末尾指向翻转区块之后的首位;
- 翻转区块之后的一份: 顺序不变,不需要改动(不需要关注)
代码:
public