Reverse Nodes in k-Group

45 篇文章 0 订阅
18 篇文章 0 订阅

主循环就是一节一节的处理,循环变量为当前节的开始结点p,终止条件为p==NULL。需要维护的变量是left outer 结点 prev。

主循环体逻辑:

1)从p往后走k步,定位到right outer 结点 q,如果走不到k步链表结束了,最后一组不到k个,不reverse,所有组处理完毕,break。

2)头插法reverse 组内结点,从第二个结点开始插,头插发的两个主要变量 head2 和 next 分别用 prev->next 域和 firstNode->next域存储。

3)为下一次循环更新prev= firstNode。

ListNode *reverseKGroup(ListNode *head, int k) 
{
	ListNode dummy(-1), *prev= &dummy;
	dummy.next= head;
	for(auto p = head; p; )
	{
		int i=0;
		auto q =p;
		for(; q && i<k; i++)
			q=q->next;
		if(i<k) break; //last group less than k, don't reverse and all groups done
		ListNode * const firstNodeInGroup=p;
		for(p=p->next; p!=q; )
		{
			firstNodeInGroup->next = p->next; //first node's next field as next variable
			p->next=prev->next; //use left outer node's next field as the head2 variable
			prev->next = p;
			p= firstNodeInGroup->next;
		}
		prev= firstNodeInGroup;
	}
	return dummy.next;
}

一个更简单版本的:

ListNode* reverseKGroup(ListNode* head, int k) {
    ListNode dummy(-1), *prev = &dummy;
    dummy.next = head;
    for (ListNode *q, *p; head; prev = head, head = q) {
        int i = 0;
        for (q = head; i < k && q; ++i) q = q->next;
        if (i < k) break;
        for (p = head, prev->next = q; p != q; ) { 
            auto next = p->next;
            p->next = prev->next;//prev->next as the head2 variable
            prev->next = p;
            p = next;
        }
    }
    return dummy.next;
}

不过还是推荐递归版本的,因为逻辑清晰

ListNode* reverseKGroup(ListNode* head, int k) {
    int i = 0;
    auto p = head;
    for (; i < k && p; ++i, p = p -> next);
    if (i < k) return head;
    ListNode* head2 = nullptr;
    for (auto q = head; q != p;) {
        auto next = q -> next;
        q -> next = head2;
        head2 = q;
        q = next;
    }
    head -> next = reverseKGroup(p, k);
    return head2;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值