LeetCode 25.k个一组翻转链表——Python实现

1、官方给的一种解法,很直观,就是指针太多,很容易绕晕

class Solution:

    def reverseKGroup(self, head: ListNode, k: int) -> ListNode:

        def reverseList(head_node, tail_node):
            new_tail_node = head_node
            visited_head = None
            while head_node != tail_node:
                add_head = head_node          # 确定当前要加入的节点
                head_node = head_node.next    # 将头结点移到下一轮要加入的节点
                add_head.next = visited_head  # 加入当前节点
                visited_head = add_head       # 更新已经翻转的链表的头节点

            tail_node.next = visited_head
            return tail_node, new_tail_node

        overall_sentinel = ListNode(0)  # overall_sentinel 作为整个链表的哨兵节点
        overall_sentinel.next = head
        current_sentinel = overall_sentinel

        while head:
            tail = current_sentinel
            # 获取长度为k的链表
            for i in range(k):
                tail = tail.next
                if tail is None:
                    return overall_sentinel.next

            next_head = tail.next
            # 对链表进行翻转,并获取当前链表的头结点和尾节点
            head, tail = reverseList(head, tail)

            # 将当前块与其前后的元素连接起来
            current_sentinel.next = head
            tail.next = next_head
            current_sentinel = tail
            head = next_head

        return overall_sentinel.next

2、自己写的一种栈+递归的方法,可能使用的内存不满足官方的要求,官方要求常数的额外空间,但是我这个方法是线性的。不过还是通过官方的测试了。

# -*- coding: utf-8 -*-
"""
@File  : stack_reverse_k_group.py
@Author: zhang_san
@Time  : 2020/8/27 10:29
@des   : 题目:K 个一组翻转链表。给你一个链表,每k个节点一组进行翻转,请你返回翻转后的链表。k是一个正整数,它的值
         小于或等于链表的长度。如果节点总数不是k的整数倍,那么请将最后剩余的节点保持原有顺序。
         其实这也是一个很典型的递归问题。每一步可以分为已经做好翻转的k个元素与reverseKGroup(剩余需要翻转的元素)的连接。
         所以在每一个函数体里面要做的是:
         (1)判断停止递归的条件,这里应该是元素个数不足k个
         (2)翻转当前的k个元素,然后最后一个元素指向下一个元素(调用函数体)
         (3)如何实现翻转,可以利用栈的"先进后出“的思想
"""
from linked_list import ListNode, generateList, printList


class Solution:
    def reverseKGroup(self, head: ListNode, k: int) -> ListNode:

        # 将k个节点压入栈中
        stack = []
        head_move = head
        for i in range(k):
            if head_move is not None:
                stack.append(head_move)
                head_move = head_move.next
            else:
                break

        # 如果栈的大小比k小,则直接返回当前子链表,不需要翻转,这里也包括转入的链表为空的情况
        if len(stack) < k:
            return head

        # 如果满足k个元素,则进行翻转,就是依次取出栈的元素进行拼接的过程
        sentinel = ListNode(0)       # 定义一个哨兵节点,用于返回翻转的链表
        stack_move = sentinel        # stack_move用于移动形成翻转链表

        while stack:
            node = stack.pop()
            node.next = None
            stack_move.next = node
            stack_move = node

        stack_move.next = self.reverseKGroup(head_move, k)

        # 将翻转好的元素与剩余需要拼接的元素进行
        return sentinel.next


L = generateList([2, 9, 10, 11, 3, 7, 4, 0, 6, -7])
s = Solution()
printList(s.reverseKGroup(L, 4))

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值