leetcode 25 K 个一组翻转链表 (c++和python)

目录

题目:

思路:

c++代码:

python代码:


题目:

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

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

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

进阶:

你可以设计一个只使用常数额外空间的算法来解决此问题吗?
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

先找到需要反转的链表片段的尾节点tail,

然后从头开始遍历链表片段,依次插入到tail后面,过程如下,1和2依次插入到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
....

如将1插入到3后面,过程: 

c++代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode* dummy = new ListNode(0);
        dummy->next = head;
        ListNode* pre = dummy;
        ListNode* tail = dummy;
        while (true)
        {
            // 找到尾节点
            for (int i = 0; i < k; i++)
            {
                tail = tail->next;
                if (tail == nullptr) return dummy->next;  // 不足k个了,返回前面已经反转后的结果
            }
            // 遍历
            head = pre->next;  // 备份开始的节点,因为这个节点会是下一次链表片段开始的节点
            while (pre->next != tail)  // 当tail没有被挤到前面之前
            {
                ListNode* cur = pre->next;  // 当前需要插入到尾节点tail后的节点
                // 将cur插入tail后
                pre->next = cur->next;
                cur->next = tail->next;
                tail->next = cur;
            }
            // 更新下一个链表片段的头节点pre和尾节点tail
            pre = head;
            tail = head;

        } 
    }
};

python代码:

class ListNode(object):
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next


class Solution:
    def reverseKGroup(self, head, k):
        dummy = ListNode(0)
        dummy.next = head
        pre = dummy
        tail = dummy
        while True:
            for i in range(k):
                tail = tail.next  # tail 移到要翻转的部分最后一个元素
                if not tail:
                    return dummy.next
            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后面 尾插法的意思就是,依次把cur移到tail后面
            # 改变 pre tail 的值
            pre = head
            tail = head


if __name__ == '__main__':
    s = Solution()
    p1 = ListNode(1)
    p2 = ListNode(2)
    p3 = ListNode(3)
    p4 = ListNode(4)
    p5 = ListNode(5)
    p1.next = p2
    p2.next = p3
    p3.next = p4
    p4.next = p5
    a = s.reverseKGroup(p1, 3)
    print(a)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.Q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值