视频讲解笔记
707. 设计链表
获取第n个节点的值
- 边界条件:n < 0 && n > len - 1
- 对于边界取值,如while循环的终止条件和current的赋值问题,带入返回第0个节点的数值,看是否会出现空指针异常或者遍历的不是第0个节点的情况。
- 实现的时候要再添加一个class ListNode用于节点的初始化,这样就更加清晰了,因为class MyLinkedList用于链表的初始化。
在头部插入新节点
- 正确插入顺序是先让newnode.next = dummy_head.next,再让dummy_head.next = newnode,也就是先接再拆,而不是先拆后接会找不到后面的节点了。
- 写成self.dummy_head.next = ListNode(val, self.dummy_head.next),非常强,很简洁
在第n个节点前插入新节点
- 仍然让current = head,那么n就是current.next,这样才能在n节点前插入新节点。
- 这里和获取第n个节点值不同的是:获取第n个节点值中current = dummy_head.next,n就是current;而这里current = dummy_head,n是current.next,其实就是current初始位置差一位的问题,原理上是一样的。
- 为什么要让current.next = n: 要在n前面插入节点,就要知道n前面一个节点的定位,所以要让current等于n前面的一个节点
删除第n个节点
- 要想删除第n个节点,要确定第n-1个节点,方便经典的做法是让current = n-1,这样current.next就是节点n,便于对current操作。
- 验证边界条件没有问题:假设删除第0个节点,current = dummy_head,那么current.next就是head,即第0个节点。
在尾部插入节点
- 则当前节点current要是尾部最后一个节点,而不是null
- 在尾部添加新节点后,默认后面就是null,不需要更改
Bug: 运行测试时none_type问题
206.反转链表
是考察基础知识的很重要一环。
双指针写法
- 没有用虚拟头节点
- current = head, pre = null. 这样在反转的时候尾结点的后面指向的才是null.
- 何时遍历结束:当current指向空指针的时候,遍历的操作结束,之后不再需要其他操作。不然会出现空指针异常或者死循环。
- 用一个临时指针temp提前将current.next保存下来,这样就不会改变方向的时候找不到后一个节点了。
递归写法
是从双指针写法来的,先掌握好双指针写法。
24. 两两交换链表中的节点
- current指向dummy head的时候,才能对节点1和2进行操作,同理,current指向2的时候,对节点3和4进行操作
- 遍历终止条件:对奇数个节点来说,current.next.next = null; 对偶数个节点来说,current.next = null——while(current.next != null) && (current.next.next = !null)。current.next != null要写在current.next.next != null前面,不然可能会发生空指针异常,因为万一current.next为空,就变成对空指针取值了
- 链表头节点:dummy_head.next
-
- 交换链表:
temp = current.next 保存
temp1 = current.next.next.next 保存- current.next = temp.next
- current.next.next = temp #节点2已经变成current.next了,注意赋值变化的情况,不要写错了
- temp.next = temp1
- 移动指针:current = current.next.next直接往后移两位
- 交换链表:
- return的头节点应该是dummy_head.next
19.删除链表倒数第N个节点
- 使用虚拟头节点,操作时无需判断是否是头节点
- 操作指针要指向要删除节点的前一个节点,才能达到要删除的目的。
- 快指针要走n步,多走一步,这样慢指针才会到要删除节点的前一个节点,达到删除的目的。⚠️注意,这里和随想录给的代码不一样的地方在于,如果判断fast.next也不为空,fast就要走n步,否则是走n+1步。
160.相交链表
- 改为复习之前刷过的labuladong相交链表题
- 等比例法
- p1 指向 A 链表头结点,p2 指向 B 链表头结点
- p1 走一步,如果走到 A 链表末尾,转到 B 链表
- p2 走一步,如果走到 B 链表末尾,转到 A 链表
- 如果相交,指针将位于交点节点,如果没有交点,值为None
- 注意p1 = p1.next if p1 else p1 = headB这样写是不对的,应该是else headB
142. 环形链表 II
- 快指针相对于慢指针每次走一个节点,所以快指针一定可以从后面追上慢指针
- 慢指针一定是在第一圈被追上,代码随想录里面有证明
- 这里快指针要走两步,所以要判断fast和fast.next两个是否为空
- 快慢指针相遇的点到头节点的中点,就是环的起点。