前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >最难链表题——LeetCode题目25:K 个一组翻转链表

最难链表题——LeetCode题目25:K 个一组翻转链表

作者头像
二环宇少
发布2020-08-13 15:38:54
7270
发布2020-08-13 15:38:54
举报

原题描述

+

给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。k 是一个正整数,它的值小于或等于链表的长度。

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

示例

给你这个链表:1->2->3->4->5

当 k=2 时,应当返回: 2->1->4->3->5

当 k=3 时,应当返回: 3->2->1->4->5
  • 你的算法只能使用常数的额外空间。
  • 你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

原题链接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group

思路解析

+

这题号称最难链表题,但如果你做过下面这道,那么思路也并不难想。

LeetCode题目24:两两交换链表中的节点

当k>2时,我们类比来看,依然要记住四个位置。

  1. K个节点组成的链表中的头节点,类似于上面题目中的first位置;
  2. K个节点组成的链表中的尾节点,类似于上面题目中的second位置;
  3. 处于K个节点之后的子链表中,首个节点的位置,类似于上面题目中的head位置;
  4. 当前操作的K个节点的链表之前的子链表中,其尾部节点的位置,类似于上面题目中prev的位置。

找到上述四个位置之后,我们只需要再将K个节点组成的子链表逆序翻转即可。但这个翻转有坑,因为你要保证在翻转之后,新的头节点和前面的子链表相连,新的尾节点与后面的子链表相连。

复杂度分析

+

  • 时间复杂度:
  • 空间复杂度:

计算步骤

+

1. 先找到四个重要位置

2. 翻转K个节点的子链表

3. 将翻转后的子链表与外部链表相连

C++参考代码

+

在实现时,我没有使用first,second的命名,而是使用了head和tail表示。此外,每次翻转之后,head指针要后移到未操作部分链表的首部,继续翻转下一个长度为K的子链表。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 * int val;
 * ListNode *next;
 * ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    pair<ListNode*, ListNode*> reverse(ListNode* head, ListNode* tail) {
        ListNode* prev = tail->next, *p = head, *q;
        while (prev != tail) {
            q = p->next;
            p->next = prev;
            prev = p;
            p = q;
        }
        return {tail, head};
    }
    
    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode *dummy = new ListNode(-1);
        dummy->next = head;
        ListNode *tail = dummy, *prev = dummy;
        while (prev) {
            for (int i = 0; i < k; ++i) {
                tail = tail->next;
                if (!tail) {
                    return dummy->next;
                }
            }
            pair<ListNode*, ListNode*> res = reverse(head, tail);
            head = res.first;
            tail = res.second;
            prev->next = head;
            head = tail->next;
            prev = tail;
        }
        return dummy->next;
    }
};
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 互联网西门二少 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档