思路:递归的终止条件是链表中没有节点,或者链表中只有一个节点时是无法进行交换的,可以直接返回该节点。否则,我们递归交换链表 head.next.next,记交换后的头节点为 cur,然后我们记 head 的下一个节点为 pre,令 pre 指向 head,而 head 指向 cur,最后返回 pre。
总结:打卡虽迟但到。自己手动画个过程图,再结合卡哥的视频讲解后,对这道题的理解加深,一下子就get到了
代码:①递归
def swapPairs(self, head):
if head is None or head.next is None: # 终止条件
return head
cur = self.swapPairs(head.next.next) # 递归,交换后的头节点
pre = head.next # head的下一个节点
pre.next = head # 指向head
head.next = cur # 指向cur
return pre
②迭代
def swapPairs(self, head):
dummy_head = ListNode(next=head) # 虚拟头结点
cur = dummy_head
while cur.next and cur.next.next: # 必须有两个才能进行交换
temp = cur.next # 先保存下来,防止被修改
temp1 = cur.next.next.next
cur.next = cur.next.next
cur.next.next = temp
temp.next = temp1
cur = cur.next.next # cur向后移两位,进行后面的交换
return dummy_head.next
思路:使用快慢指针,快指针先移动N步,快慢指针再同时移动。当快指针指向空时,慢指针指向的就是目标,但因为要先找到节点的前一个,所以快指针要先走N+1步。
总结:多看多学,把别人的思路搞会了,就是你的思路~
代码:①快慢指针
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
# 删除链表中的倒数第N个节点
dummy_head = ListNode(next=head)
slow = fast = dummy_head
# 快指先走N+1步
for i in range(n + 1):
fast = fast.next
# 快慢指针同时走,直到fast指针到达末尾,此时slow到达倒数第N个节点的前一个节点
while fast:
slow = slow.next
fast = fast.next
# 删除slow指针的下一个节点,重新连接
slow.next = slow.next.next
return dummy_head.next
思路:题目让求的是链表相交的节点,所以a 、b的指针都要走一遍headA、headB两个链表,a、b相遇的地方就是相交的点。
总结:其实光看题目描述的时候给我搞懵逼了,但后面看人家的题解评论乐了,解题还整上浪漫氛围了呢。“错过的人就算走过的路依然会错过。而注定相遇的人,就算走到尽头见不到你,我也会走你走过的路,而你也走过我走过的路”!!!!行了,行了,代码我搞不会,这浪漫我依然搞不会。就应该叉出去(bushi)
代码:①
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
if not headA or not headB:
return None
A, B = headA, headB
# 遍历指针相交点
while A != B:
A = A.next if A else headB
B = B.next if B else headA
return A
代码②
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
# 初始化指针还有长度
flagA, flagB = headA, headB
lenA, lenB = 0, 0
# 求链表A的长度
while flagA:
flagA = flagA.next
lenA += 1
# 链表B的长度
while flagB:
flagB = flagB.next
lenB += 1
# 重新定向表头
flagA, flagB = headA, headB
if lenA > lenB:
flagA, flagB = flagB, flagA
lenA, lenB = lenB, lenA
# 让指针flagA移到和B链表同等长度的位置上
for _ in range(lenB - lenA):
flagB = flagB.next
# 然后两个指针flagA和flagB同时遍历
while flagA:
if flagA == flagB:
return flagA
else:
flagA = flagA.next
flagB = flagB.next
# 没有相遇,返回 None
return None
思路:其规律是用一个快指针fast和慢指针slow,快指针每次走两步,慢指针每次走一步,若有环的情况下他们两个肯定是会重合的。
总结:不会写代码的总结不是一个好总结,好吧,我不是一个好总结。今天学得有点多,需要好好消化一下,其实在学习完了后,总结时是会让知识在脑子里哗啦啦的翻一遍,把学到的东西再重新巩固了一下。脑电量有点低了,散了吧~~~
代码:
def detectCycle(self, head: ListNode):
fast = head
slow = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast: # 快慢指针重合说明存在环,再派一个指针从头节点和慢指针同步移动
slow = head
while slow != fast:
slow = slow.next
fast = fast.next
return slow # 新指针和慢指针重合的节点即为环入口节点
return None