LeetCode 25 —— K 个一组翻转链表

1. 题目

2. 解答
  • 首先,利用快慢指针确定链表的总结点数。

  • 偶数个结点时,结点个数等于 i * 2。

  • 奇数个结点时,结点个数等于 i * 2 + 1。

  • 然后将链表的每 K 个结点划分为一组。循环对每组的子链表进行翻转,并依次拼接起来。

  • 最后,将多余的结点拼接在新链表最后面即可。

  • 代码如下

/**
 * 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) {
        
        if (head == NULL || head->next == NULL || k == 1) //空链表或只有一个结点或者 k=1 不用翻转,直接返回
        {
            return head;
        }
        else
        {
            int node_num = 0; // 链表的结点个数
            ListNode* slow = head;
            ListNode* fast = head;
            
            // 利用快慢指针确定链表的结点总个数
            while(fast && fast->next)
            {
                slow = slow->next;
                fast = fast->next->next;
                node_num++;
            }
            
            if (fast) // 奇数个结点
            {
                node_num = node_num * 2 + 1;
            }
            else // 偶数个结点
            {
                node_num = node_num * 2;
            }
            
            int reverse_time = node_num / k; // 需要翻转链表的次数
            
            // 链表结点数小于 k,不需要翻转链表
            if (reverse_time == 0)
            {
                return head;
            }
            else
            {
                ListNode* temp = head; // 保存链表的头结点
                ListNode* tail = head; // 翻转后子链表的尾结点

                ListNode* p1 = head;
                ListNode* p2 = head;
                ListNode* p3 = NULL;

                for (int i = 0; i < reverse_time; i++)
                {
                    p2 = p2->next;

                    // 进行 k-1 次翻转
                    for (int j = 0; j < k-1; j++)
                    {
                        p3 = p2->next;
                        p2->next = p1;
                        p1 = p2;
                        p2 = p3;
                    }

                    if (i == 0)
                    {
                        temp = p1; // 第一轮翻转,temp 指向翻转后的新链表的头结点
                    }
                    else
                    {
                        tail->next = p1; // 连接翻转后的子链表
                    }

                    tail = head; // 指向翻转后的新链表的尾结点
                    head = p2; // 指向后面待翻转链表的第一个结点
                    p1 = p2;
                }

                tail->next = head; // 连接多余的结点

                return temp;
            }
            
        }     
    }
};
复制代码

获取更多精彩,请关注「seniusen」!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值