24. 两两交换链表中的节点
cur指针必须在需要操作的两个节点前面,可以直接画个链表,最重要的是指针改变的顺序,标蓝色的两根线会断掉,必须先保存两个指针的值(cur.next和cur.next.next.next)
19. 删除链表的倒数第 N 个结点
初步想法:倒数第N个,正数是size-N个节点(方便遍历),cur是倒数第N个节点,pre是前一个,直接让pre指向cur后一个节点
验证发现Python中需要自己定义函数获取链表的长度:
这个方法实现的程序:
class Solution:
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
dummy_head=ListNode(next=head)
cur=dummy_head
size=0
while cur.next:
cur=cur.next
size+=1(求链表的长度,好像应该用while cur?这里cur是从dummy 开始的,所以是while cur.next)
cur=dummy_head
for i in range(size-n):
cur=cur.next
cur.next=cur.next.next
return dummy_head.next
学习视频:操作节点必须是删除节点的前一个节点,利用双指针找到倒数第N个节点的位置,fast比slow先走N步,这样fast到最后一个节点时,slow在N前面一个节点,正好操作N这个节点
class Solution:
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
dummy_head=ListNode(next=head)
fast=dummy_head
slow=dummy_head
for i in range(n):
fast=fast.next
while fast.next:
fast=fast.next
slow=slow.next
slow.next=slow.next.next
return dummy_head.next
初始想法:链表相交的点条件是curA.next=curB.next,但由于链表长度不一样,curA和curB可能需要移动不同的步数才能走到相交点(如curA两步,curB三步),没有想到如何操作这个不同?
题解:假设A<B,则让curB先走sizeB-size A 步,这样curA和curB就能同时移动到相交点
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
curA=headA
curB=headB
sizeA=0
sizeB=0
while curA:
curA=curA.next
sizeA+=1(求链表的长度)
while curB:
curB=curB.next
sizeB+=1
curA=headA
curB=headB
if sizeA>sizeB:
curA,curB=curB,curA
sizeA,sizeB=sizeB,sizeA(保证链表B是长的那个,这样不用重复步骤操作两次)
for i in range(sizeB-sizeA):
curB=curB.next
while curA:
if curA==curB:
return curA
else:
curA=curA.next
curB=curB.next(不要忘记遍历操作)
return None
初始想法:环形链表没有指向None的节点,如何遍历链表?(也有None节点的)
如何实现链表中有某个节点,可以通过连续跟踪 next
指针再次到达?
视频题解:利用快慢指针,如果快慢指针相遇,则一定有环。fast一次走两步,slow一次走一步,在进入环内后,快指针走一圈后一定能追上慢指针。若快指针一次走N步,可能会跳过慢指针。
初始想法:设置头尾两个指针,同时向中间走,如果头与尾的值总是相等,就是回文的
但这是链表,不是数组,尾指针是不能向前走的
题解:把链表的值复制到数组里面然后用双指针法来比较
class Solution:
def isPalindrome(self, head: ListNode) -> bool:
val=[]
cur=head
while cur:
val.append(cur.val)(复制链表的值到数组,用append)
cur=cur.next
return val==val[::-1](头尾两两比较,记住这个用法)