[小专题]链表反转

链表反转[小专题]

刚刚开始刷题的小白一只,多多指教!

1. 反转整个链表

Leetcode 206 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

递归求解,要将递归函数抽象成概念,方便理解。reverseList函数功能是反转一个以head为头节点的链表。关注点:使用函数反转head.next之后,只需要聚焦对于head的处理就可以。

class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        # 可以使用递归的思路解决反转链表的问题
        if not head or not head.next:
            return head
        if head and not head.next:
            return head
        node = self.reverseList(head.next)
        """此时head的下一个节点是尾部节点,需要的操作时将head变成尾部节点的下一个节点"""
        head.next.next = head
        """之后将head.next = None防止形成循环链表"""
        head.next = None
        return node

2. 反转前N个节点

反转前N个节点和反转整个链表逻辑上基本类似,唯一不同在于本题需要一个successor指针,这个指针用于指向第N+1个节点。反转完前N个节点之后,需要将前N个的尾节点指向successor,““连接起来””。

"""使用reverseN 反转整个链表"""
class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if not head:
            return None
        cur = head
        cnt = 0
        while cur:
            cnt += 1
            cur = cur.next
        return self.reverseN(head, cnt)[0]
    
    """反转前N个节点"""
    def reverseN(self, head, n):
    	"""如何获得successor指针指向的位置"""
        if n == 1:
            successor = head.next
            return head, successor
        new_head, successor = self.reverseN(head.next, n - 1)
        head.next.next = head
        head.next = successor
        return new_head, successor

3.反转链表某个区间内的节点

Leetcode 92 给你单链表的头指针 head 和两个整数 left 和 right,
其中 left <= right。请你反转从位置 left 到位置 right 的链表节点,返回反转后的链表。

这个题目可以借助2中的reverseN函数,寻找到left节点作为头节点,之后使用reverseN反转前right-left+1个节点。注意在left的前一个位置留一个指针,方便后续连接,因此引入一个虚拟头节点dum是很有必要的。在学习labuladong代码的时候发现第二个函数有递归的写法,但我个人更容易理解直接while遍历的写法。

class Solution:
    def reverseN(self, head, n):
        if n == 1:
            successor = head.next
            return head, successor
        node, successor = self.reverseN(head.next, n-1)
        head.next.next = head
        head.next = successor
        return node, successor
	"""递归的写法"""
    # def reverseBetween(self, head: Optional[ListNode], left: int, right: int) -> Optional[ListNode]:
    #     if left == 1:
    #         return self.reverseN(head, right)[0]
    #     head.next = self.reverseBetween(head.next, left-1, right-1)
    #     return head

    def reverseBetween(self, head: Optional[ListNode], left: int, right: int) -> Optional[ListNode]:
        cur = dum = ListNode(-1)
        dum.next = head
        cnt = -1
        while cur:
            cnt+=1
            if cnt+1 == left:
                pre = cur
                node = cur.next
                break
            cur = cur.next
        pre.next = self.reverseN(node, right-left+1)[0]
        return dum.next

4. K 个一组翻转链表

给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
# TODO: 
  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值