K 个一组翻转链表 【LeetCode 25】

题目描述

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

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

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

分析

这个题的思路很简单,就是模拟。翻转链表我们都知道,这个题加了一个条件,K个一组。

这就带来了一些额外需要考虑的问题:

怎么限制只翻转K个?

  • 可以计数(s<k),也可以使用指针判断(t!=tail)。

K个一组翻转完毕后,怎么和前后的部分连接起来?

  • 翻转之前这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:
    //翻转的头指针head,第K+1个节点是K1_node  也就是翻转之后尾指针要指向K+1个节点。
    ListNode* reverse(ListNode* K1_node,ListNode* head,int K){ 
        ListNode* a=K1_node;
        ListNode* b=head;
        //cout<<"test "<<b->val<<endl;
        int s=0;
        while (s<K){
            ListNode* c=b->next;
            b->next=a;
            a=b;
            b=c;
            s++;
        }
        //cout<<"test "<<a->val<<endl;	
        return a;
    }
    ListNode* reverseKGroup(ListNode* head, int K) {
        ListNode* new_head=NULL; //新的头指针 
        ListNode* a=head; //翻转之前的头 
        ListNode* tail=NULL; //翻转之后的尾 
        ListNode* t=head; //用于遍历每组的第K+1个 
        bool b=0; //用来判断总数是否小于K个
        while (1){
            int s=0;
            while (t!=NULL){ //数出K个 
                t=t->next;
                s++;
                if (s==K) break;
            }
            if (s!=K) break; //说明不够K个,就不需要翻转了。 
            if (new_head==NULL){
                new_head=reverse(t,a,K); //第一次翻转的头是新链表的头 
                b=1;
            } else {
                ListNode * p=reverse(t,a,K); //之后的头需要和之前的连接 
                tail->next=p;  //连接上一段的尾和下一段的头 
            }
            tail=a; //之前的头 翻转之后成为 尾
            a=t; //下一段的翻转之前的头是t
        }
        if (b==0) new_head=head;
        return new_head; 
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值