【困难】25. K 个一组翻转链表

struct ListNode【singly-linked list】
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
图2-5 单链表结构

alt

单链表的结点结构
typeded struct node{//结构名为node
  T Element;//元素域Element 用户自定义的元素类型T
  struct node* Link;//指针域Link
}Node;//单链表的结点类型Node
std::pair class template

https://www.cplusplus.com/reference/utility/pair/?kw=pair

pair<ListNode*, ListNode*> myReverse(ListNode* head, ListNode* tail) {}
pair<ListNode*, ListNode*> result = myReverse(head, tail);

Pair of values

This class couples together a pair of values, which may be of different types (T1 and T2). The individual values can be accessed through its public members first and second.

Pairs are a particular case of tuple. alt

std::tie function template

https://www.cplusplus.com/reference/tuple/tie/?kw=tie

 tie(head, tail) = myReverse(head, tail);

Tie arguments to tuple elements

Constructs a tuple object whose elements are references to the arguments in args, in the same order.

This allows a set of objects to act as a tuple, which is especially useful to unpack tuple objects.

The special constant ignore can be used to specify elements of a tuple to be ignored instead of tied to a specific object. alt

25. K 个一组翻转链表

https://leetcode-cn.com/problems/reverse-nodes-in-k-group/

给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。

k 是一个正整数,它的值小于或等于链表的长度。

如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

进阶:

你可以设计一个只使用常数额外空间的算法来解决此问题吗? 你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。 alt

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {

    }
};
模拟
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    // 翻转一个子链表,并且返回新的头与尾
    pair<ListNode*, ListNode*> myReverse(ListNode* head, ListNode* tail) {
        ListNode* prev = tail->next;
        ListNode* p = head;
        while (prev != tail) {
            ListNode* nex = p->next;
            p->next = prev;
            prev = p;
            p = nex;
        }
        return {tail, head};
    }

    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode* hair = new ListNode(0);//新建一个节点
        hair->next = head;//,把它接到链表的头部,
        ListNode* pre = hair;//让它作为 pre 的初始值,这样 head 前面就有了一个节点,就可以避开链表头部的边界条件。

        while (head) {
            ListNode* tail = pre;
            // 查看剩余部分长度是否大于等于 k
            for (int i = 0; i < k; ++i) {//对于每个分组,我们先判断它的长度是否大于等于 k。
                tail = tail->next;
                if (!tail) {
                    return hair->next;//否则不需要翻转。
                }
            }
 			 //若是,我们就翻转这部分链表,
            ListNode* nex = tail->next;
            // 这里是 C++17 的写法,也可以写成
            // pair<ListNode*, ListNode*> result = myReverse(head, tail);
            // head = result.first;
            // tail = result.second;
            tie(head, tail) = myReverse(head, tail);
            // 把子链表重新接回原链表
            pre->next = head;
            tail->next = nex;//将子链表的头部与上一个子链表连接,
            pre = tail;
            head = tail->next;//以及子链表的尾部与下一个子链表连接。
        }

        return hair->next;//只要返回它的下一个节点就好了。
    }
};

alt

力扣题解 文章被收录于专栏

边做边写 参考力扣官方题解和《数据结构:C语言描述(第3版)》

全部评论

相关推荐

勤奋努力的椰子这就开摆:美团骑手在美团工作没毛病
投递美团等公司10个岗位
点赞 评论 收藏
分享
11-18 09:44
Java
小白也想要offer:简历别放洋屁,搞不还还放错了,当然你投外企除外,以上纯属个人观点
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务