C++实现LeetCode(25.每k个一组翻转链表)
[LeetCode] 25. Reverse Nodes in k-Group 每k个一组翻转链表
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.
Example:
【C++实现LeetCode(25.每k个一组翻转链表)】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
Note:
- Only constant extra memory is allowed.
- You may not alter the values in the list's nodes, only nodes itself may be changed.
-1->1->2->3->4->5以此类推,只要 cur 走过k个节点,那么 next 就是 cur->next,就可以调用翻转函数来进行局部翻转了,注意翻转之后新的 cur 和 pre 的位置都不同了,那么翻转之后,cur 应该更新为 pre->next,而如果不需要翻转的话,cur 更新为 cur->next,代码如下所示:
|||
precur next
-1->3->2->1->4->5
|||
curpre next
解法一:
class Solution {public:ListNode* reverseKGroup(ListNode* head, int k) {if (!head || k == 1) return head; ListNode *dummy = new ListNode(-1), *pre = dummy, *cur = head; dummy->next = head; for (int i = 1; cur; ++i) {if (i % k == 0) {pre = reverseOneGroup(pre, cur->next); cur = pre->next; } else {cur = cur->next; }}return dummy->next; }ListNode* reverseOneGroup(ListNode* pre, ListNode* next) {ListNode *last = pre->next, *cur = last->next; while(cur != next) {last->next = cur->next; cur->next = pre->next; pre->next = cur; cur = last->next; }return last; }};
我们也可以在一个函数中完成,首先遍历整个链表,统计出链表的长度,然后如果长度大于等于k,交换节点,当 k=2 时,每段只需要交换一次,当 k=3 时,每段需要交换2此,所以i从1开始循环,注意交换一段后更新 pre 指针,然后 num 自减k,直到 num
class Solution {public:ListNode* reverseKGroup(ListNode* head, int k) {ListNode *dummy = new ListNode(-1), *pre = dummy, *cur = pre; dummy->next = head; int num = 0; while (cur = cur->next) ++num; while (num >= k) {cur = pre->next; for (int i = 1; i < k; ++i) {ListNode *t = cur->next; cur->next = t->next; t->next = pre->next; pre->next = t; }pre = cur; num -= k; }return dummy->next; }};
我们也可以使用递归来做,用 head 记录每段的开始位置,cur 记录结束位置的下一个节点,然后调用 reverse 函数来将这段翻转,然后得到一个 new_head,原来的 head 就变成了末尾,这时候后面接上递归调用下一段得到的新节点,返回 new_head 即可,参见代码如下:
解法三:
class Solution {public:ListNode* reverseKGroup(ListNode* head, int k) {ListNode *cur = head; for (int i = 0; i < k; ++i) {if (!cur) return head; cur = cur->next; }ListNode *new_head = reverse(head, cur); head->next = reverseKGroup(cur, k); return new_head; }ListNode* reverse(ListNode* head, ListNode* tail) {ListNode *pre = tail; while (head != tail) {ListNode *t = head->next; head->next = pre; pre = head; head = t; }return pre; }};
到此这篇关于C++实现LeetCode(25.每k个一组翻转链表)的文章就介绍到这了,更多相关C++实现每k个一组翻转链表内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- MybatisPlus使用queryWrapper如何实现复杂查询
- python学习之|python学习之 实现QQ自动发送消息
- 孩子不是实现父母欲望的工具——林哈夫
- opencv|opencv C++模板匹配的简单实现
- Node.js中readline模块实现终端输入
- 【Leetcode/Python】001-Two|【Leetcode/Python】001-Two Sum
- java中如何实现重建二叉树
- leetcode|leetcode 92. 反转链表 II
- 人脸识别|【人脸识别系列】| 实现自动化妆