算法训练营day3

链表理论基础

0.链表基础

  1. 由指针串联每个节点构成的线性结构

  2. 每个节点包括数据域(data)和指针域(next)

  3. 类型:

    1. 单链表:next指向下一个节点
    2. 双链表:既有next,又有pre(pre指向前一个节点)
    3. 循环链表:收尾相连,即最后一个结点的next指向head的data
  4. 存储方式

    1. 由于链表是根据指针对数据进行串联的,其在内存中并不是连续存储的,而是散乱的分布在内存中的某地址上,具体根据操作系统的内存管理决定。
  5. 定义:手写链表

    1. 注意:如果不定义构造函数使用默认构造函数的话,在初始化的时候就不能直接给变量赋值
  6. 操作:

    1. 删除

    2. 添加

    3. 链表的增添和删除都是O(1)操作,也不会影响到其他节点。

      但是要注意,要是删除最后一个节点,需要从头节点查找到倒数第第二个结点通过next指针进行删除操作,查找的时间复杂度是O(n)。

  7. vs数组

    1. 数组适用于数据量固定,频繁查询,增删较少
    2. 链表相反
1.移除链表元素

通过设置虚拟节点来使删除所有节点的逻辑相同,pre.next = cur.next;

最后记得返回的是 dummy.next 而不是head ;因为dummy永远指向头结点,而head随着遍历不断向后移动,pre也不断向后移动

2.设计链表

结合上一个问题,使用虚拟前驱结点来使 处理所有节点的逻辑相同,更容易复现代码

  1. val / next / size / head = new ListNode(0)初始化虚拟头结点
  2. 增加节点时,注意建立cur当前节点和next节点的联系(cur.next = pre.next)
    • 如果先建立pre和cur的联系(pre.next = cur) 会导致next结点的丢失
3.反转链表
  1. 迭代&递归方式都可
    1. 区别,递归空间复杂度O(n),迭代空间复杂度O(1);时间复杂度相等
  2. 理解为什么要用指针保存next&pre
    1. 初始状态下有head和head.next是可以进行操作的节点
    2. 显然pre需要保存,因为无法直接访问到
    3. 那么next为什么要保存呢?因为要进行反转操作,head.next 指向了pre,从而丢失了next节点,因此需要保存next
    4. 这样的话有两个变量pre,next即可;通过测试,将cur全部换成head一样可以成功运行代码
  • 8
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值