链表中的节点每k个一组翻转
- 描述
将给出的链表中的节点每 k 个一组翻转,返回翻转后的链表
如果链表中的节点数不是 k 的倍数,将最后剩下的节点保持原样
你不能更改节点中的值,只能更改节点本身。
如果链表中的节点数不是 k 的倍数,将最后剩下的节点保持原样
你不能更改节点中的值,只能更改节点本身。
数据范围: 0≤n≤2000 , 1≤k≤2000 ,链表中每个元素都满足 0≤val≤1000
要求空间复杂度 O(1),时间复杂度 O(n)
要求空间复杂度 O(1),时间复杂度 O(n)
例如:
给定的链表是 1→2→3→4→5
对于 k=2 , 你应该返回 2→1→4→3→5
对于 k=3 , 你应该返回 3→2→1→4→5
- 算法思想
此题使用递归较为方便
step 1:每次从进入函数的头节点优先遍历链表k次,分出一组,若是后续不足k个节点,不用反转直接返回头。
step 2:从进入函数的头节点开始,依次反转接下来的一组链表,反转过程同反转链表的题目。
step 3:这一组经过反转后,原来的头变成了尾,后面接下一组的反转结果,下一组采用上述递归继续。
具体过程如下图(k=3为例):
递归过程
回溯过程
最底层返回的是第一个分组的pre,也就是新链表的头结点。
- 代码
1 /** 2 * struct ListNode { 3 * int val; 4 * struct ListNode *next; 5 * }; 6 */ 7 8 #include <cstddef> 9 class Solution { 10 public: 11 /** 12 * 13 * @param head ListNode类 14 * @param k int整型 15 * @return ListNode类 16 */ 17 ListNode* reverseKGroup(ListNode* head, int k) { 18 ListNode *tail=head; 19 //遍历k次 20 for(int i=0;i<k;i++){ 21 if(tail==nullptr) return head; 22 tail=tail->next; 23 } 24 //反转当前段 25 ListNode *pre=nullptr; 26 ListNode* cur=head; 27 while(cur!=tail){ 28 ListNode* temp=cur->next; 29 cur->next=pre; 30 pre=cur; 31 cur=temp; 32 } 33 //递归 34 head->next=reverseKGroup(tail,k); 35 //返回当前段的pre,用来连接前一段的链表 36 return pre; 37 } 38 };
参考:https://blog.nowcoder.net/n/7a045d18a2b049379ca97f6b408f2691?f=comment
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探