zoukankan      html  css  js  c++  java
  • LeetCode 25. K 个一组翻转链表

    题目


    给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。

    k 是一个正整数,它的值小于或等于链表的长度。

    如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

    示例:

    给你这个链表:1->2->3->4->5
    
    当 k = 2 时,应当返回: 2->1->4->3->5
    
    当 k = 3 时,应当返回: 3->2->1->4->5
    

    说明:

    你的算法只能使用常数的额外空间。
    你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。


    思路

    这个题目和上个题目很像,不过,这里是定义变数交换,并且不够k次保持原有顺序。

    这里记录下powcai大大的题解,思路和代码都比自己清晰太多了,sad~~

    继续取经学习ang...

    方法一:

    用栈,我们把 k 个数压入栈中,然后弹出来的顺序就是翻转的!

    这里要注意几个问题:

    • 第一,剩下的链表个数够不够 k 个(因为不够 k 个不用翻转);

    • 第二,已经翻转的部分要与剩下链表连接起来。

    class Solution(object):
        def reverseKGroup(self, head, k):
            """
            :type head: ListNode
            :type k: int
            :rtype: ListNode
            """
            dummy = ListNode(0)
            p = dummy
            while True:
                count = k 
                stack = []
                tmp = head
                while count and tmp:
                    stack.append(tmp)
                    tmp = tmp.next
                    count -= 1
                # 注意,目前tmp所在k+1位置
                # 说明剩下的链表不够k个,跳出循环
                if count : 
                    p.next = head
                    break
                # 翻转操作
                while stack:
                    p.next = stack.pop()
                    p = p.next
                #与剩下链表连接起来 
                p.next = tmp
                head = tmp
            
            return dummy.next
    

    方法二:

    尾插法。

    直接举个例子:k = 3

    pre
    tail    head
    dummy    1     2     3     4     5
    # 我们用tail 移到要翻转的部分最后一个元素
    pre     head       tail
    dummy    1     2     3     4     5
    	       cur
    # 我们尾插法的意思就是,依次把cur移到tail后面
    pre          tail  head
    dummy    2     3    1     4     5
    	       cur
    # 依次类推
    pre     tail      head
    dummy    3     2    1     4     5
    		cur
    ....
    
    class Solution(object):
        def reverseKGroup(self, head, k):
            """
            :type head: ListNode
            :type k: int
            :rtype: ListNode
            """
            dummy = ListNode(0)
            dummy.next = head
            pre = dummy
            tail = dummy
            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 #插在tail后面
                # 改变 pre tail 的值
                pre = head 
                tail = head
            return dummy.next
    

    方法三:

    递归。

    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
            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
    
    

    Note:

    刷到25题了,这25应该已经囊括了几乎大部分算法的处理思想,现在开始复习这些题目,等真正刷到熟练的时候再继续往下刷。

    o。o

  • 相关阅读:
    几款免费的支持HTML5的音频视频转换软件推荐
    2 宽度优先爬虫和带偏好的爬虫(4)
    Hadoop源代码分析(三)
    Hadoop源代码分析(四)
    C# 收邮件
    关于Adobe flash palyer 安装出现的问题解决方案
    C#调用java类、jar包方法。
    EF 4.3 的一些基础使用
    .net数据库连接池问题:在同一页面使用一段时间后,提示超时,连接池不够用这类的提示!
    使用Google CDN的JSAPI服务来提供加载各类JS库的方法
  • 原文地址:https://www.cnblogs.com/xiaoqiangink/p/13964913.html
Copyright © 2011-2022 走看看