首页 > 试题广场 >

链表中的节点每k个一组翻转

[编程题]链表中的节点每k个一组翻转
  • 热度指数:252329 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
将给出的链表中的节点每 k 个一组翻转,返回翻转后的链表
如果链表中的节点数不是 k 的倍数,将最后剩下的节点保持原样
你不能更改节点中的值,只能更改节点本身。

数据范围: ,链表中每个元素都满足
要求空间复杂度 ,时间复杂度
例如:
给定的链表是
对于 , 你应该返回
对于 , 你应该返回

示例1

输入

{1,2,3,4,5},2

输出

{2,1,4,3,5}
示例2

输入

{},1

输出

{}

说明:本题目包含复杂数据结构ListNode,点此查看相关信息
模拟法,用快指针跑K步找到每一段需要反转的链表的最后一个节点,之后反转slow和fast指针之间的链表,将反转完的链表拼接在slow的后面,同时尾部连接上剩余的链表。每次开始新的一段时slow和fast都指向已完成反转的新链表的最后一个节点。
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param head ListNode类 
# @param k int整型 
# @return ListNode类
#
class Solution:
    def reverseKGroup(self , head: ListNode, k: int) -> ListNode:
        # write code here
        if k==1&nbs***bsp;head is None:
            return head
        newHead = fast = slow = ListNode(-1)
        fast.next = head
        slow.next = head
        
        while True:
            for _ in range(k):
                fast = fast.next
                if fast is None:
                    break
            if fast is None:
                break
            else:
                pre = None
                tail = cur = slow.next
                for _ in range(k):
                    tmp = cur.next
                    cur.next = pre
                    pre = cur
                    cur = tmp

                slow.next= pre
                tail.next = cur
                fast = slow = tail
                

        return newHead.next


发表于 2023-10-23 12:03:46 回复(0)
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param head ListNode类 
# @param k int整型 
# @return ListNode类

class Solution:
    def reverseKGroup(self , head: ListNode, k: int) -> ListNode:
        # write code here
        a=[]
        s=[]
        while head:#遍历所有节点
            a.append(head.val)#将遍历到的节点加入a列表
            head=head.next
            if len(a)==k:#如果长度达到k则翻转
                for i in range(k):
                    s.append(a.pop())
        if len(a)<k:#长度不足k,直接保留
            for i in range(len(a)):
                s.append(a[i])             
        res=ListNode(0)#列表转链表
        cur=res
        for i in s:
            cur.next=ListNode(i)
            cur=cur.next
        return res.next
        

发表于 2023-10-17 20:48:53 回复(0)
#核心思想是将链表节点值取出放至数组内,在数组内调整哥元素位置,最后将调整好位置的元素按顺序赋值给链表各节点
class Solution:
    def reverseKGroup(self , head: ListNode, k: int) -> ListNode:
        # 创建空列表存放链表节点数值
        var_list = []
        cur = head
        # 遍历链表,将链表节点值取出追加到数组内
        while cur:
            var_list.append(cur.val)
            cur = cur.next
        # 将数组长度对k取商,数组前n*k位元素就是需要调整顺序的,n*k以后的顺序不变
        n = len(var_list)//k
        # 如果列表元素少于k个,直接返回原链表
        if not n:
            return head
        # 调整列表元素顺序
        else:
            for i in range(n):
                for j in range(k):
                    min_index = i*k+j
                    max_index = (i+1)*k-j-1
                    if min_index <= max_index:
                        var_list[min_index],var_list[max_index] = var_list[max_index],var_list[min_index]
        cur = head
        # 将调整好顺序的列表各元素按顺序赋值给链表节点
        while cur :
            cur.val = var_list.pop(0)
            cur = cur.next
        return head



发表于 2023-07-14 10:44:00 回复(0)
## 递归实现
class Solution:
    def reverse(self, head, k):
        p = head
        if head is None:
            return p
        end = ListNode(head.val)
        start = end
        for i in range(1, k):
            if head is None:
                return p
            if head.next is None:
                return p
            head = head.next
            node = ListNode(head.val)
            node.next = start
            start = node
        end.next = self.reverse(head.next, k)
        return start

    def reverseKGroup(self , head: ListNode, k: int) -> ListNode:
        if head is None:
            return head
        start = self.reverse(head, k)
        return start

发表于 2023-06-27 00:27:53 回复(0)
解题思路:
类:
    定义组内反转函数:
        变量tail赋值头指针
        组内遍历:
            如果变量为空:    
                返回头指针
            如果不为空:
                变量指向下一个节点    
        初始化pre变量,用于指向组内链表值
        变量cur赋值为头指针
        如果cur 不为空:
            cur的下一个节点赋值给temp临时变量
            pre赋值给cur的下一个节点
            cur当前节点值赋值给pre
            temp值赋值给cur
        调用函数
        返回pre值
        
发表于 2023-06-04 21:28:48 回复(0)
# 核心思想是先把链表转换成数组,再最后将处理好的数组重构成链表

class Solution:
    def reverseKGroup(self , head: ListNode, k: int) -> ListNode:
        # write code here
        vals = []
        n = 0
        while head:
            vals.append(head.val)
            head = head.next
            n += 1
        times = n // k  #判断一共要做多少次交换
        rverse = []  #用来保存交换的结果
        rr = []  #用来保存最后的结果,因为不一定做整数次的交换
        for i in range(0,times):  #交换该交换的部分
            begin = k * i
            end = k + begin
            rev = vals[begin:end][::-1]
            for j in rev:
                rverse.append(j)
        #保存一下没有交换的部分
        if n % k != 0:
            rr = rverse + vals[k * times:]
        else:
            rr = rverse
        #重构链表
        res = ListNode(0)
        cur = res
        for i in rr:
            cur.next = ListNode(i)
            cur = cur.next
        return res.next


发表于 2023-05-22 14:54:56 回复(0)
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param head ListNode类 
# @param k int整型 
# @return ListNode类
#
class Solution:
    def reverseKGroup(self , head: ListNode, k: int) -> ListNode:
        # write code here
        new_head = ListNode(0)
        new_head.next=head

        c=0
        last=new_head
        cur = new_head
        while cur:
            if c==k:
                cur=self.reverse(last,k)
                last=cur
                c=0
            c+=1

            cur=cur.next
        return new_head.next

    def reverse(self, last, k):
        queue_head=last.next
        for i in range(1, k):
            next=queue_head.next
            queue_head.next=next.next
            next.next=last.next
            last.next=next
        return queue_head


发表于 2023-04-15 17:07:18 回复(0)
class Solution:
    def reverseKGroup(self , head: ListNode, k: int) -> ListNode:
        # write code here
        res=ListNode(0)
        res.next=head
        pre=res # 指向进行反转部分链表的前序
        cur=head # 指向进行反转部分链表头
        while cur:
            tail=cur
            for i in range(0,k): # 判断要不要翻转
                if tail==None:
                    return res.next
                else: tail=tail.next
            for i in range(1,k): # 翻转
                temp=cur.next
                cur.next=temp.next
                temp.next=pre.next
                pre.next=temp
            cur=cur.next # 指向下一部分列表头
            for i in range(0,k):
                pre=pre.next
        return res.next
一次性循环跑完……
发表于 2023-03-16 16:20:08 回复(2)
    def reverseKGroup(self , head: ListNode, k: int) -> ListNode:
        # write code here
        newHead = ListNode(0)
        newHead.next = head
        
        i = 0
        while head:
            head = head.next
            i += 1
        total_num = i
        reverse_time = total_num // k

        head = newHead.next
        pre = newHead
        while reverse_time>0:
            reverse_time -= 1
            for i in range(k-1):
                tmp = head.next
                head.next = tmp.next
                tmp.next = pre.next
                pre.next = tmp
            if reverse_time != 0:
                head = head.next
                for i in range(k):
                    pre = pre.next

        return newHead.next

发表于 2023-03-01 23:51:22 回复(0)
def reverseKGroup(self , head: ListNode, k: int) -> ListNode:
    # write code here
    le = 0
    # 虚拟头结点
    hv = ListNode(0)
    hv.next = head
    t = hv
    # 计算长度
    while t.next is not None:
        le += 1
        t = t.next
    rev_time = le // k # 共需翻转rev_time次
    pre = hv
    cur = hv.next
    p,c = pre,cur # 暂存pre和cur
    for _ in range(rev_time):# 共需翻转rev_time次
        for _ in range(k):# 每次翻转k个元素
            temp = cur.next
            cur.next = pre
            pre = cur
            cur = temp
        # 连接头尾结点并更新p和c
        p.next = pre
        p = c
        c.next = cur
        c = cur
    return hv.next

发表于 2023-02-22 15:52:58 回复(0)
class Solution:
    def reverseKGroup(self , head: ListNode, k: int) -> ListNode:
        # write code here
        tail = head
        for _ in range(k):
            if tail is None:
                return head
            tail = tail.next
        pre = None
        cur = head
        for _ in range(k):
            temp = cur.next
            cur.next = pre
            pre = cur
            cur = temp
        head.next = self.reverseKGroup(cur, k)
        return pre

发表于 2023-02-09 16:07:59 回复(0)
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param head ListNode类 
# @param k int整型 
# @return ListNode类
#
class Solution:
    def reverseBetween(self , head: ListNode, m: int, n: int) -> ListNode:
        # write code here
        p0 = ListNode(-1)
        p0.next = head
        p1 = head
        p3 = head
        p2 = p0
        
        for _ in range(1, m):
            p1 = p1.next
            p2 = p2.next
            p3 = p3.next
        
        for _ in range(m, n+1):
            if not p3:
                return p0.next, True
            p3 = p3.next

        for _ in range(m, n):
            temp = p1.next
            p1.next = temp.next
            temp.next = p2.next
            p2.next = temp
        
        return p0.next, False


    def reverseKGroup(self , head: ListNode, k: int) -> ListNode:
        # write code here

        if not head&nbs***bsp;not head.next&nbs***bsp;k == 1:
            return head
            
        terminate = False
        start = 0
        while not terminate:
            head, terminate = self.reverseBetween(head, start+1, start+k)
            start += k
        
        return head

发表于 2023-01-03 15:57:43 回复(0)
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param head ListNode类 
# @param k int整型 
# @return ListNode类
#思路
#1.对原链表剩余部分每k个节点计数为一组,切断链表
#2.将切出的子链表翻转,记录翻转后链表头节点,尾结点
#3.将每次切出并翻转的链表拼接到结果链表
#4.重复1-3,直至原链表遍历结束

class Solution:
    #翻转链表方法
    def reverseChain(self,head:ListNode):
        tail = None
        p = head
        while p:
            temp = p.next
            p.next = tail
            tail = p
            p = temp
        return tail
    #获取链表尾结点方法
    def getTain(self,head:ListNode):
        p = head
        i = 1
        while p.next:
            i += 1
            p = p.next
        return p,i

    def reverseKGroup(self , head: ListNode, k: int) -> ListNode:
        # write code here
        #如果k为1,返回原链表
        if k == 1:
            return head
        #如果k比原链表长度大,返回原链表
        if head and self.getTain(head)[1] < k:
            return head
        p = head
        i = 1
        s = None
        res = None
        while p:
            #获取每一段切分链表的头结点
            if i%k == 1:
                s = p
                p = p.next
                i += 1
            #切分完成后与结果链表res连接
            elif i%k == 0:
                temp = p.next
                p.next = None
                #首次切分时
                if i == k:
                    res = self.reverseChain(s)
                else:
                    res_tail = self.getTain(res)[0]
                    res_tail.next = self.reverseChain(s)
                i += 1
                p = temp
            else:
                p = p.next
                i += 1
            #如果剩余不足k长度的子链表,直接连接入结果链表
            if not p and (i-1)%k != 0:
                res_tail = self.getTain(res)[0]
                res_tail.next = s
        return res

发表于 2022-12-10 02:20:24 回复(0)
利用上一题”链表内指定区间反转“的成果
class Solution:
    def reverseKGroup(self , head: ListNode, kint) -> ListNode:
        if not head or not head.next:
            return head
        new_node = ListNode(-1)
        new_node.next = head
        index = 0
        while head:
            index += 1
            head = head.next
            if index % k == 0:
                new_node.next = self.reverseBetween(new_node.next, index -k + 1, index)
        return new_node.next

    #链表内指定区间反转
    def reverseBetween(self , head: ListNode, mintnint) -> ListNode:
        res = ListNode(-1)
        res.next = head
        pre = res
        cur = head
        for i in range(1,m):
            pre = cur
            cur = cur.next
        for i in range(m,n):
            temp = cur.next
            cur.next = temp.next
            temp.next = pre.next
            pre.next = temp
        return res.next


发表于 2022-09-24 21:45:38 回复(0)
为什么我这个只有一半通过率呢,求教
class Solution:
    def reverseKGroup(self , head: ListNode, k: int) -> ListNode:
        # write code here
        if not head:
            return None
        res = ListNode(-1)
        res.next = head
        pre = res
        cur = pre.next
        length = 0
        while head:
            length+=1
            head = head.next
        if length < k:
            return res.next
        else:
            for a in range(1,length%k+1):
                #找到循环位置
                for i in range(1,(a-1)*k+1):
                    pre = cur
                    cur = cur.next
            #开始循环
            for i in range(1,k):
                temp = cur.next
                cur.next = temp.next
                temp.next = pre.next
                pre.next = temp
        return res.next


发表于 2022-09-17 02:25:05 回复(0)
class Solution:
    def reverseKGroup(self , head: ListNode, k: int) -> ListNode:
        # write code here
        if k==1: return head
        if not head: return head
        linklist = []
        cnt = 0
        cur_k = []
        while head:
            cur_k.append(head)
            cnt += 1
            if cnt == k:
                linklist.extend(cur_k[::-1])
                cur_k = []
                cnt=0
            head = head.next
        linklist.extend(cur_k)
        dummy_head = ListNode(-1)
        last_node = dummy_head
        for node in linklist:
            last_node.next = node
            last_node = node
        last_node.next = None
        return dummy_head.next

发表于 2022-07-29 23:57:36 回复(0)
class Solution:
    def reverseKGroup(self , head: ListNode, k: int) -> ListNode:
        # write code here 
        dummy = ListNode(0)
        dummy.next = head
        j = 0
        # 获取链表长度
        while head:
            head = head.next
            j = j + 1
        if j == 0:
            return
        total_times = j // k   # 需要翻转的总次数
        times = 0    # 第times次翻转
        i = 0
        previous = dummy
        head = dummy.next
        while previous.next and times < total_times:
            # 进入第times次翻转
            # 要反转k个元素的链表只需操作k-1次,故先令i+1
            i = i + 1
            while i // k == times:
                previous_next = previous.next
                previous.next = head.next
                head.next = previous.next.next
                previous.next.next = previous_next
                i = i + 1
            previous = head
            head = head.next
            times = times + 1
        return dummy.next  

发表于 2022-05-21 16:21:18 回复(0)

问题信息

难度:
25条回答 25338浏览

热门推荐

通过挑战的用户