LeetCode(C++)刷题计划:25-K个一组翻转链表

25-K个一组翻转链表

@Author:CSU张扬
@Email:csuzhangyang@gmail.com or csuzhangyang@qq.com

Category Difficulty Pass rate Tags Companies
algorithms Medium 72.20% linked-list facebook / microsoft

1. 题目

给你一个链表,每 kk 个节点一组进行翻转,请你返回翻转后的链表。
kk 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 kk 的整数倍,那么请将最后剩余的节点保持原有顺序。

示例:
给定这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5

说明 :

你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group

2.解法

2.1 解法一:递归解法

总的来说,这道题就是多次反转链表。

1. 如何反转链表?

  1. 我们需要三个指针 pre, cur, next ,分别指向前一个结点、当前结点、后一个结点。
  2. 注意:当 cur 指向第一个结点时,我们要令 pre = nullptr
  3. 我们先保存好下一个节点:next = cur->next 。再反转当前结点和前一个结点: cur->next = pre 。然后 pre, h 都向后移一次:pre = h; h = next
  4. 需要反转几个结点即循环几次。

2. 递归返回值和如何使用返回值?

  1. 应该返回反转之后的头结点(也就是反转之前的尾结点),这里就是 pre
  2. 令反转之后的尾结点(也就是反转之前的头结点)指向下一次递归的返回值(也就是下一次递归的反转后的头结点)。

3. 递归什么时候结束?

当剩余结点数不足 kk 个时,我们的递归函数要先检查结点数有没有 kk 个。

执行用时: 20 ms, 在所有 cpp 提交中击败了97.34%的用户
内存消耗: 9.5 MB, 在所有 cpp 提交中击败了98.88%的用户

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode* temp = head;
        for (auto i = 0; i < k; ++ i) {
            if (temp == nullptr) {
                return head;
            }
            temp = temp->next;
        }
        ListNode* h = head;
        ListNode* pre = nullptr;
        for (auto i = 0; i < k; ++ i) {
            ListNode* next = h->next;
            h->next = pre;
            pre = h;
            h = next;
        }
        head->next = reverseKGroup(h, k);
        return pre;
    }
};
原文地址:https://www.cnblogs.com/MagicConch/p/12179145.html