每K个节点一组翻转链表 Leetcode 25 和剑指 Offer 24 反转链表 Python

(一)Leetcode 25  每K个节点一组翻转链表

利用栈结构

首先能想到的当然是通过栈的结构,来进行反转,设置一个栈,先进后出的性质。唯一需要注意的当剩余的元素不足以放到栈里面的时候,就停止反转就好来。

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def reverseKGroup(self, head, k):
        """
        :type head: ListNode
        :type k: int
        :rtype: ListNode
        """
        #用于链接头元素
        Phead = ListNode(None)
        p = Phead
        while True:
            count = k
            stack = []
            tmp = head
            while count and tmp:
                stack.append(tmp)
                tmp = tmp.next
                count -= 1
            #跳出上面循环的时候,tmp是第k+1的元素来
            #如果上面循环结束的时候,count还不为0,那就代表不足k个元素
            if count :
                p.next = head
                break
            #对k个元素进行反转
            while stack:
                p.next = stack.pop()
                p = p.next
            #与剩下链表链接起来
            p.next = tmp
            head = tmp
        return Phead.next

尾插法

思路就是用一个指针指向头节点,一个指向尾部节点,让头节点连接尾部节点所连接的节点。然后让之前头部节点连接的节点,连接头部节点,一直到第一个节点为尾部节点。
eg,1,2,3,4,5,k=3,之前1连接的是2,现在让1,连接4,2之前连接的3,然后让他连接1,3之前连接4,现在连接2,然后让3成为头节点,从4开始往后继续。

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def reverseKGroup(self, head, k):
        """
        :type head: ListNode
        :type k: int
        :rtype: ListNode
        """
        Phead = ListNode(None)
        Phead.next, pre ,tail = head, Phead, Phead
        while True:
            count = k
            while count and tail:
                count -= 1
                tail = tail.next
            if not tail:break
            head = pre.next
            while pre.next!= tail:
                #得到下一个元素
                cur = pre.next
                # pre与cur.next 连接起来,画图可以看出来
                #cur是新的链表的第一个节点
                pre.next = cur.next
                cur.next = tail.next
                #每次第一个节点都要知道插谁后面,这一句就是为了更新
                tail.next = cur
            
            #当前面都已经反转完毕,就要进行要一个k组的转换,需要更新,pre和tail
            #按照k=3的例子,此时pre和tail就指向1这个节点,而我们第一步创建的pre和tail
            #指向的是我们自己建立的节点
            #感受一下建立一个新的头节点的好处
            pre = head
            tail= head
        return Phead.next

递归法

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def reverseKGroup(self, head, k):
        """
        :type head: ListNode
        :type k: int
        :rtype: ListNode
        """
        cur = head
        count = 0
        while cur and count != k:
            cur = cur.next
            count += 1
        #通过设置cur,把原先的链表切成几段,每一段在一个递归体里面进行处理。
        if count == k:
            cur = self.reverseKGroup(cur,k)
            while count:
                tmp = head.next
                head.next = cur
                cur = head
                head = tmp
                count -= 1
            head = cur
        return head

(二)Python实现链表反转

链表反转(while迭代实现):

  • 链表的反转引入一个cur_node变量,表示当前节点;同时需要引入一个变量new_link表示反转后的新链表;while循环内还需中间变量tmp存放当前节点的后继节点,防止原链表数据丢失。

  • 在while循环内(循环条件为 cur_node !=None,若设置为cur_node.next将导致最后一个节点无法反转到新链表):

    • 首先需要将当前节点的后继节点传递给中间变量tmp
    • 当前节点指向新链表new_link
    • 当前节点指向新链表new_link后,新链表头结点更新为当前节点cur_node
    • 将中间变量tmp传递给cur_node,开始新一轮循环
    • 循环结束后返回 new_link
class Node(object):
    def __init__(self, value=None, next=None):
        self.value = value
        self.next = next

    @staticmethod
    def reverse(head):
        cur_node = head  # 当前节点
        new_link = None  # 表示反转后的链表
        while cur_node != None:
            tmp = cur_node.next  # cur_node后续节点传递给中间变量
            cur_node.next = new_link    # cur_node指向new_link
            new_link = cur_node    # 反转链表更新,cur_node为新的头结点
            cur_node = tmp    # 原链表节点后移一位
        return new_link

link = Node(1, Node(2, Node(3, Node(4, Node(5, Node(6, Node(7, Node(8, Node(9)))))))))
root = Node.reverse(link)
while root:
        print(root.value)
        root =root.next

 

递归实现:

  • 递归实现与while实现不同在于递归首先找到新链表的头部节点,然后递归栈返回,层层反转

  • 首先找到新链表的头结点(即遍历到原链表的最后一个节点返回最后节点)

  • 执行函数体后续代码,将原链表中的尾节点指向原尾节点的前置节点

  • 前置节点的指针指向None(防止出现死循环)

  • 返回新链表的头部节点至上一层函数,重复以上操作

    def reverse2(self,head):
        new_head = None
        if head == None:
            return None
        if head.next == None:  # 递归停止的基线条件
            return head
        new_head = self.reverseList(head.next)
        head.next.next = head	# 当前层函数的head节点的后续节点指向当前head节点
        head.next = None	# 当前head节点指向None
        return new_head
        

       

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值