24. 两两交换链表中的节点
- 题目
24.两两交换链表中的节点
https://leetcode.cn/problems/swap-nodes-in-pairs/
复习前
1)有了昨天模拟的经验,把需要的节点和要存储的节点列出来,并把交换顺序捋清楚,写的非常顺畅,30min内搞定
2)小小纠结了下cur.next.next = tmp的意义
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def swapPairs(self, head: ListNode) -> ListNode:
# 模拟交换过程 p1与p2交换,存储p2.next 需要prev记录p1.prev
# prev, p1=cur tmp = cur.next.next prev.next=cur.next cur.next.next=cur
# cur.next =tmp prev, cur = cur.next, cur.next.next(从1、2到3、4)
# 分奇数个 跳出条件为cur.next or cur==None 返回phead.next
phead = ListNode(next=head)
prev, cur = phead, head
while cur and cur.next:
tmp = cur.next.next # 存储3
prev.next = cur.next # prev指向2
cur.next.next = cur # 2指向1
cur.next = tmp # 1指向3
prev, cur = cur, cur.next #交换
return phead.next
2.文章+视频链接:
讲解
19.删除链表的倒数第N个节点
1.题目:
https://leetcode.cn/problems/remove-nth-node-from-end-of-list/
复习前:
也还比较顺畅,只是有点纠结index初始值的设定,我觉得这个可以先写,写完再根据过程优化
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
# 如果第一个节点要删除此时需引入虚拟头节点作为返回值
# 对链表设置两个遍历,形成相差n-1的步长,出口为cur==None
# 删除节点:prev.next = prev.next.next
index = 1
phead = ListNode(next=head)
fn, en = phead, head
while index < n:
en = en.next
index += 1
while en.next:
fn, en = fn.next, en.next
fn.next = fn.next.next
return phead.next
2.文章+视频链接:
讲解
160.链表相交
1.题目:面试题 02.07. 链表相交
https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/
复习前:
虽然写的有点繁琐,但我也觉得跟答案思路差不多,更好理解
2.文章+视频链接
讲解
142.环形链表II
1.题目:142.环形链表II
https://leetcode.cn/problems/linked-list-cycle-ii/solution/
复习前:
这个题的思路是伤,但是我记得要用快慢指针所以虽然写出来了但不太理解
而且我写的有点繁琐,一定要注意如何优化哦!
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
# 如果把两个循环结合起来就不需要这么多判断了,因为此时外循环就不需要fn != sn,则便于写初始化条件sn, fn = head, head
if not head or not head.next or not head.next.next:
return None
sn, fn = head.next, head.next.next
while fn and fn.next and fn != sn:
# print("我在第一部循环")
fn = fn.next.next
sn = sn.next
if not fn or not fn.next:
return None
sn1 = head
while sn1 != sn:
# print("我在第二部循环")
sn1 = sn1.next
sn = sn.next
return sn
2.文章+视频链接
讲解
推荐看视频
复习效果:
终于搞懂了为什么要定义2倍速的1倍速的指针,为什么快慢指针一定相遇,且在慢指针进入第一个环相遇