代码随想录第三天 || 链表理论基础 || 203.移除链表元素 || 707.设计链表 || 206.反转链表

今日激励:今日事,今日毕,一切困难都是纸老虎!!

目录

一:链表的理论基础

203 :移除链表元素

题目链接:203. 移除链表元素 - 力扣(LeetCode)

题目要求:

思路分析 

代码如下:

 本题收获

707  设计链表

题目链接:707. 设计链表 - 力扣(LeetCode)

题目要求:

解题记录

思路分析

 本题收获

206 反转链表

题目链接:

        206. 反转链表 - 力扣(LeetCode)

题目要求

思路分析

代码如下:

 本题收获


一:链表的理论基础

数据结构中的链表和数组的存储方式不一样,链表中的节点可以分散在不同的位置,在java中引用存放对象在堆内存中的地址,所以链表节点这个对象包含了两部分内容,一部分是自己的值val,另一部分是next,存放下一个节点在堆内存中的地址。(java中没有指针的概念,只有引用)

链表中主要应用的是单链表中的增加和删除节点,不适用查找节点,因为要一个一个遍历。

无论是增加还是删除节点,需要找到前驱节点,然后修改前驱结点的next值,所以创建一个虚拟节点,将处理第一个节点和其他节点的操作统一起来。 以及便于返回新的头结点。

203 :移除链表元素

题目链接:203. 移除链表元素 - 力扣(LeetCode)

题目要求:

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。

思路分析 

  1. 创建一个虚拟节点,如果第一个节点需要删除,此时需要修改虚拟节点的next 值,统一了操作。
    ListNode dummy =new ListNode (-1,head);
    // 调用构造函数,以及val=-1,将dummy的next值设置为head。
  2. 找到被删除节点的前驱节点,此时要注意从虚拟节点开始找,存在第一个节点就是要删除的元素。
  3. 易错点 如何写while() 中的判断条件?
    1. 注意是 while(temp!=null&& temp.next!=null),为什么这样写,是因为temp始终指向被删除元素的前驱,我也必须要保证temp.next!=null;
    2. temp何时移动? while()循环中有一个if()判断条件,必须是if条件不满足之后,也就是说temp 所指向节点的下一个节点的值不等于val时,才能移动。示例 :val=7,链表是7→7→7→7;这个也是我的一个错误点。
  4. 最后返回虚拟节点返回新的头结点

代码如下:

 本题收获

  1. 这是第一次学了java之后,解决的第一道链表题目(之前是c++),加深了对于java中引用的理解和使用。
  2. 这道题目自己之前写过,过去的时间比较久,今天第一遍没有直接写对,在思考的过程中加深了自己对于细节和边界的理解

707  设计链表

题目链接:707. 设计链表 - 力扣(LeetCode)

题目要求:

设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val 和 nextval 是当前节点的值,next 是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性 prev 以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。

解题记录

 第一次拿到这个题目时,单看其中的方法每一个都不难,但是我没有办法和这个题目要求结合起来,没有做到“设计”,当写到第三个方法时,我查看了“代码随想录”上的答案,有点知道自己是哪里出的问题。 根据题目要求,这是要求设计一个链表,首先要选择是单链表还是双链表。

我选择单链表,以及整个链表的属性有哪些? 第一个是链表的长度,默认值是0,以及为链表设置虚拟节点,方便后续的操作。只有先设计好属性,写方法的时候思路才能更完善。

思路分析

  1. 注意事项:在这个题目中链表的索引是从0开始,不是1,我第一遍是从默认从1开始写代码,报错,再重新修改!要认真读题,不是“默认”。
  2. 涉及到了几个方法,重点是插入、删除,这个时候需要找到被删除(或者是插入位置)元素的前驱元素,然后修改next的值。
  3. 因为链表的最大索引和size差1,所以从虚拟节点开始遍历的话,count从-1 开始。
  4. 当链表发生变化时,记得更新size值。

代码如下

 本题收获

  • 这个是教训,要认真读题,链表的索引也可以从0开始。 
  • 理解了一点“设计”,MyListedList类,是一种模板,在test方法中可以创建该对象,然后调用该类的方法,实现相应的功能。所以要先想好MyListedList类中的属性。
  • java语言中使用“引用”来代替指针的寻址功能,引用保存对象在堆内存中的地址。
  • 增加了单链表中插入、删除操作的熟练度。

206 反转链表

题目链接:

        206. 反转链表 - 力扣(LeetCode)

题目要求

        给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。输入:head = [1,2,3,4,5] 输出:[5,4,3,2,1]。

思路分析

  1. 这个题在力扣上是“简单题”,一个注意事项是:在修改当前节点的next值指向前驱节点时,在发生修改之前,需要先保存当前节点的后继,以免后续节点丢失。
  2. 如何让第一个节点的操作和后续其他节点保持一致?我自己尝试增加一个虚拟头结点,并且我让虚拟头结点的next指向了head,这里有一个问题:就是虚拟头结点依然指向第一个节点,形成了一个闭环,报错。
    1. 一个是让pre的初始值设为null,这时第一个节点和后续节点的操作是一致的,因为pre会在while循环中向前移动
    2. 第二个改进措施 :增加一个虚拟节点,但是这个节点一开始并不指向head,单纯的增加一个节点,然后最后释放,有一点麻烦。
      1. 经过测试,这个方法不行,因为无法释放最早创建的虚拟节点。最早的头结点指向了这个节点,无法直接释放

代码如下:

 本题收获

  • 增加了自己的动手能力,报错“有环的时候”,自己画图找到环在哪里。
  • 培养了自己独立思考的能力,正如之前的提出的问题“如何保证第一个节点的操作和其他节点一样,然后想到了增加虚拟节点,然后事实上发现又产生了环的问题”看完代码随想录之后,又想到了一开始不让虚拟节点指向头结点,发现反转链表后不能释放虚拟节点,也加深了对正确代码的理解和记忆。提高了动手能力
  • 需要先保存当前节点的next值,再去修改指向前驱,保证后续节点不丢失。

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值