反转链表:
提供一个链表头部节点head,返回反转后的链表的头部,这是最基础的部分。
代码如下:
pre = None
cur = head
while cur:
tmp = cur.next
cur.next = pre
pre = cur
cur = tmp
return pre
反转链表Ⅱ,给你单链表的头指针 head
和两个整数 left
和 right
,其中 left <= right
。请你反转从位置 left
到位置 right
的链表节点,返回 反转后的链表 。
我们可以对left到right这些节点 单独进行反转,反转之后,再把这个反转之后的链表链接到第left-1个节点和第right+1个节点之间。这样就完成了反转和链接。
代码如下:
dummy = ListNode(next=head)
p0 = dummy
# p0在循环之后得到的是第left-1个节点,如果left = 1, 那么我们就得到dummy(哨兵节点)
for _ in range(left-1):
p0 = p0.next
pre = None
cur = p0.next
# 取自上述反转链表的代码块,每次操作我们把cur往后移动一位,最后我们需要得到
# cur是第right+1个节点(这就是为什么我们前面用的是while cur)
# 那么我们需要操作right - left + 1次
for _ in range(right-left+1):
nex = cur.next
cur.next = pre
pre = cur
cur = nex
# cur为第right + 1个节点,pre是第right个节点
# 注意这个时候p0的next仍然是第left个节点,反转之后第left个这个节点的next节点应该是
# 第right + 1个节点 即cur
# 第right个节点应该是p0的下一个节点,即p0.next = pre
# 代码如下:
p0.next.next = cur
p0.next = pre
return dummy.next
K个一组反转链表:
给你链表的头节点 head
,每 k
个节点一组进行翻转,请你返回修改后的链表。
k
是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k
的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
注意到反转链表Ⅱ是反转长度为right-left+1的链表,然后再把这个链表链接到原来的链表之上,这一题是该题的稍微延展。每k个节点进行一次反转。
n = 0
cur = head
while cur:
n += 1
cur = cur.next
p0 = dummy = ListNode(next=head)
pre = None
cur = head
while n >= k: #剩下的节点小于k直接结束
n -= k
for _ in range(k):
nxt = cur.next
cur.next = pre
pre = cur
cur = nxt
# 通过上一题我们知道现在得到的cur是要反转的链表的下一个节点
# p0的next节点是要反转的链表的头节点
# 要做的是把反转之后的链表的尾节点,与cur链接,反转之后的链表的尾节点就是p0的next节点
# nxt是p0的next节点,将nxt与cur链接即可
nxt = p0.next
nxt.next = cur
# 其次我们要做的是,将反转之后的头节点与p0链接,反转之后的头节点为反转之前的尾节点,即为pre
# 所以p0.next = pre
p0.next = pre
# p0 设置为nxt,他的角色相当于反转链表Ⅱ的第left-1个节点,承担链接链表的作用
p0 = nxt
return dummy.next
代码思想from灵神