每K个一组反转链表

这篇博客介绍了如何实现链表的翻转操作,具体是按每k个节点一组进行翻转。提供了两种示例代码,分别展示了如何创建、打印链表以及进行翻转操作。当k值变化时,链表的翻转结果也会随之改变,如k=2时,链表变为21435;k=3时,链表变为32145。

给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序。

说明:

1. 你需要自行定义链表结构,将输入的数据保存到你的链表中;

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

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

输入描述:

第一行输入是链表的值
第二行输入是K的值,K是大于或等于1的整数

输入形式为:
1 2 3 4 5
2

输出描述:

当 k = 2 时,应当输出:
2 1 4 3 5

当 k = 3 时,应当输出:
3 2 1 4 5

当k=6时,应当输出:
1 2 3 4 5

输入例子1:

1 2 3 4 5
2

输出例子1:

2 1 4 3 5

示例代码:

#  data structure
class LinkNode(object):
    def __init__(self, val):
        self.val = val
        self.next = None


#  create linklist
def create_link(link):
    if not link:
        return
    p = head = LinkNode(link[0])
    for i in link[1:]:
        p.next = LinkNode(i)
        p = p.next
    return head


#  print linklist
def print_link(head):
    while head:
        print(head.val, end=' ')
        head = head.next
    print()


#  reverse linklist
def reverse_link(head, k):
    p = new_head = LinkNode(0)
    while True:
        stack = []
        count = k
        tmp = head
        while count and tmp:
            stack.append(tmp)
            tmp = tmp.next
            count -= 1
        if count:
            p.next = head
            break
        while stack:
            p.next = stack.pop()
            p = p.next
        head = tmp
    return new_head.next


a = [1, 2, 3, 4, 5, 6]
obj = create_link(a)
print_link(obj)
result = reverse_link(obj, 4)
print_link(result)

运行效果:

 示例代码2:

#  data structure
class LinkNode(object):
    def __init__(self, val):
        self.val = val
        self.next = None


#  create linklist
def create_link(link):
    if not link:
        return
    p = head = LinkNode(link[0])
    for i in link[1:]:
        p.next = LinkNode(i)
        p = p.next
    return head


#  print linklist
def print_link(head):
    while head:
        print(head.val, end=' ')
        head = head.next
    print()


#  reverse linklist
def reverse_link(head, k):
    p = new_head = LinkNode(0)
    while True:
        stack = []
        count = k
        tmp = head
        while count and tmp:
            stack.append(tmp)
            tmp = tmp.next
            count -= 1
        if count:
            p.next = head
            break
        while stack:
            p.next = stack.pop()
            p = p.next
        head = tmp
    return new_head.next


a = [1, 2, 3, 4, 5, 6]
a = (input('请输入列表数据:'))
a = a.split()
k = int(input('请输入k:'))
obj = create_link(a)
print_link(obj)
result = reverse_link(obj, k)
print_link(result)

运行效果:

### 实现方法 在链表操作中实现每 `k` 个节点一组进行反转,通常采用递归和迭代相结合的方法。该方法的核心思想是分组处理链表中的节点,每组包含 `k` 个节点,并对每组内的节点进行反转,最后将反转后的子链表重新连接起来。 #### 1. 反转指定区间的链表 首先,需要实现一个辅助函数来反转链表中从 `start` 到 `end` 的子链表。该函数的核心逻辑是将指定区间内的节点逐个反转[^1]。例如,可以使用迭代的方式反转链表: ```python def reverse(start, end): prev = None curr = start while curr != end: next_node = curr.next curr.next = prev prev = curr curr = next_node return prev ``` #### 2. 分组处理链表 接下来,通过递归的方式遍历整个链表并分组处理。每次从链表的当前头部开始,找到一组 `k` 个节点,如果不足 `k` 个节点,则直接返回链表的头部,无需反转。否则,对这 `k` 个节点进行反转,并递归处理后续的链表部分[^3]。 ```python def reverseKGroup(head, k): if head is None: return head a = b = head # 找到第k个节点 for _ in range(k): if b is None: return head b = b.next # 反转前k个节点 new_head = reverse(a, b) # 递归处理后续的链表,并连接当前组的末尾 a.next = reverseKGroup(b, k) return new_head ``` #### 3. 处理细节 在具体实现时,需要注意以下几点: - **边界条件**:当链表长度不足 `k` 时,直接返回原始链表。 - **断开连接**:在反转链表之前,需要将该子链表从原链表中暂时断开,避免反转时影响其他部分。 - **重新连接**:反转完成后,将反转后的子链表重新连接到原链表中,并处理前后指针的指向。 #### 4. 时间复杂度与空间复杂度 - **时间复杂度**:由于每个节点最多会被访问两次(一次用于遍历,一次用于反转),因此总的时间复杂度为 `O(n)`,其中 `n` 是链表的长度。 - **空间复杂度**:递归调用栈的深度最多为 `n/k`,因此空间复杂度为 `O(n/k)`。 #### 5. 示例图解 以链表 `1 -> 2 -> 3 -> 4 -> 5` 和 `k=2` 为例: - 第一组反转 `1 -> 2`,得到 `2 -> 1`。 - 第二组:反转 `3 -> 4`,得到 `4 -> 3`。 - 最后一组:`5` 不足一组,保持原样。 - 最终链表:`2 -> 1 -> 4 -> 3 -> 5`。 通过上述方法,可以高效地实现链表中每 `k` 个节点一组反转操作。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值