LeetCode 25. Reverse Nodes in k-Group(反转单链表每k个结点)

本文介绍了一种算法,该算法将给定链表中每K个节点进行翻转,并详细解析了实现思路及代码细节。适用于LeetCode 24题目的进阶版本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:

    Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.
    k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.
    You may not alter the values in the nodes, only nodes itself may be changed.
    Only constant memory is allowed.
    For example, Given this linked list: 1->2->3->4->5
    For k = 2, you should return: 2->1->4->3->5
    For k = 3, you should return: 3->2->1->4->5

分析:
    题意:给定一个单链表,对于每k个的结点,反转它们的顺序(最后不足k个结点的部分保持原序),并返回结果。
    思路:这道题是LeetCode 24的进化版本,同样考察头插法(之前有说明,头插法逆序,尾插法正序)。为了方便操作,我们用指针h建立一个空结点(方便指针s的操作,同时保存最终结果)。这里跟LeetCode 24的区别:我们不能用一个flag来处理,假设单链表包含n个结点,则总共需要反转的有T=[n/k]个段,剩余部分保持原序。对于每个段,我们用period变量来统计当前处理结点的位置,如果period等于k,则当前段处理完毕、period清零,此时指针s指向下一段结点的开始位置。
    时间复杂度为O(n)。

代码:

#include <bits/stdc++.h>

using namespace std;

struct ListNode{
	int val;
	ListNode *next;
	ListNode(int x): val(x), next(NULL){}
};

class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        // Exceptional Case: 
		if(!head || !head->next){
			return head;
		}
		ListNode * p = head, *r;
		ListNode *h = new ListNode(-1), *s = h;
		int n = 0;
		while(p){
			n++;
			p = p->next;
		}
		p = head;
		int T = n / k, period = 0, cnt = 0;
		// debug
		// cout << "n: " << n << ", T: " << T << endl;
		if(T == 0){
			return head;
		}
		// every k nodes: head insert method
		while(p){
			period++;
			r = p;
			p = p->next;
			r->next = s->next;
			s->next = r;
			if(period == k){
				for(int i = 1; i <= k; i++){
					s = s->next;
				}
				period = 0;
				cnt++;
				if(cnt == T){
					break;
				}
			}
		}
		s->next = p;
		return h->next;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值