zoukankan      html  css  js  c++  java
  • 数据结构与算法 —— 链表linked list(04)

    我们在上篇文章里面提到了链表的翻转,给定一个链表,对每两个相邻的节点作交换,并返回头节点,今天的这道题是它的升级版,如下:

    k个一组翻转链表

    给出一个链表,每 个节点一组进行翻转,并返回翻转后的链表。

    是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 的整数倍,那么将最后剩余节点保持原有顺序。

    示例 :

    给定这个链表:1->2->3->4->5

    当 = 2 时,应当返回: 2->1->4->3->5

    当 = 3 时,应当返回: 3->2->1->4->5

    说明 :

    • 你的算法只能使用常数的额外空间。

    • 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

    解题思路:

        这道题让我们以每K个为一组来翻转链表,实际上是把原链表分成若干个小段,然后对没一个小段进行翻转。那么我们就能想到他是需要两个函数的,一个是来做分段的,一个是在对每一段做翻转的。我们就以题中给出的例子来看的话,1>2>3>4>5, k=3.一般在处理链表问题的时候,因为单向链表是不可逆的,只能从前往后遍历,所以我们一般在开头添加一个头结点,记录当前最新的头结点,值一般给为-1,那么新的链表就变为了-1>1>2>3>4>5.k=3,那么我们需要把1>2>3做翻转,做翻转的时候我们需要两个指针,pre和next分别指向要被翻转的链表的前后的位置,在这里也就是pre=-1,next=4,那么翻转完1>2>3之后变为-1>3>2>1>4>5,这个时候的pre指针应该是1。如下:

        

    -1->1->2->3->4->5
     |           |
    pre         next

    -1->3->2->1->4->5 | |         pre next

    就这样循环,只要循环了k个节点,就可以调用翻转函数来进行局部的翻转,翻转函数返回翻转后的链表的新的pre节点,实现方法如下:

    def reverseOneGroup(pre_node, next_node):
        last_node = pre_node.next
        cur_node = last_node.next
        while cur_node != next_node:
            last_node.next = cur_node.next
            cur_node.next = pre_node.next
            pre_node.next = cur_node
            cur_node = last_node.next
    
        return last_node
    

      

    在翻转函数中,定义两个三个指针,一个是pre指针,一个是last指针,一个是cur指针,pre指针是链表的头指针,cur指针是目前循环到的节点指针,last指针是当前循环到指针cur的前置节点指针,每次翻转cur的时间,只需要把last的next指向cur的next,cur的next指向pre的next,pre的next指向cur就好,然后cur就迭代下一个node,为last的next指针。总体的实现代码如下:

    # Definition for singly-linked list.
    class ListNode(object):
        def __init__(self, x):
            self.val = x
            self.next = None
    
    
    def reverseOneGroup(pre_node, next_node):
        last_node = pre_node.next
        cur_node = last_node.next
        while cur_node != next_node:
            last_node.next = cur_node.next
            cur_node.next = pre_node.next
            pre_node.next = cur_node
            cur_node = last_node.next
    
        return last_node
    
    
    class Solution(object):
        def reverseKGroup(self, head, k):
            """
            :type head: ListNode
            :type k: int
            :rtype: ListNode
            """
            if k == 1 or not head:
                return head
            dump = ListNode(-1)
            dump.next = head
            pre = dump
            cur = head
            i = 0
            while cur:
                i += 1
                if i % k == 0:
                    pre = reverseOneGroup(pre, cur.next)
                    cur = pre.next
                else:
                    cur = cur.next
    
            return dump.next
    

      

    我的这个实现方法应该是我能想到的最常规,最简单的算法,肯定会有其他的算法实现,大家可以探讨一下,比如在一个函数里实现,比如像上一篇文章一样使用递归,大家可以一起交流,欢迎给我留言,交流。

    coding交流群:226704167,,郑州程序员群:59236263愿和各位一起进步!

    微信公众号:

  • 相关阅读:
    NodeJS、NPM安装配置步骤(windows版本)
    23种设计模式全解析
    js阻止浏览器默认事件
    js获取不同浏览器盒子宽度高度
    H5之重力感应篇
    JS中的call()和apply()方法
    html学习笔记
    less(css)语言快速入门
    power designer简单教程
    Strom开发配置手册
  • 原文地址:https://www.cnblogs.com/lip0121/p/8883558.html
Copyright © 2011-2022 走看看