[leetcode-链表]25. k个一组翻转链表

给出一个链表,每 个节点一组进行翻转,并返回翻转后的链表。

是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 的整数倍,那么将最后剩余节点保持原有顺序。

示例 :

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

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

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

说明 :

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

//=======================================================================

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* reverseKGroup(struct ListNode* head, int k) {
    //处理特殊条件
    if(head == NULL || head->next == NULL || k<=1)
    {
        return head;
    }
    
    //先找到第一组,包含k个元素,newHead指向第一组后面的第一个结点
    struct ListNode *newHead = head;
    int count=0;
    while(newHead && count < k)
    {
        newHead = newHead->next;
        count += 1;
    }    
    
    //    1,     2,     3,        4,       5   k=2
    //  head           newHead             newHead
    //           temp
    //    ---------------->
    // newHead
    //           head
    //                  temp
    //     
    
    //如果第一组可以找全,则进行翻转; 反之,不需要翻转
    if(count == k)
    {
        //同理,处理后续元素的k组翻转,最后返回翻转后的头结点newHead
        newHead = reverseKGroup(newHead, k);
        
        //对前面k个元素进行翻转
        struct ListNode *temp=NULL;
        while(count > 0)
        {
            temp = head->next; //备份第二个结点
            
            head->next = newHead; //两组衔接过渡 ,第一个的下一个结点为下一组翻转后的头结点 
            
            newHead = head;  //此时的第一个为合并数据后的部分的第一个 
            
            head = temp; //第二个为新的头 
            
            count -= 1;
        }
        
        head = newHead;
    }
    
    return head;
}

 

//=======================================================================

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *reverseList(struct ListNode *head, int k)
{
    struct ListNode *pnext=head;
    while(pnext && k>0) //找到k个元素的下一个元素
    {
        pnext=pnext->next;
        k--;
    }
    
    if(k>0) //不到k个元素,则无需翻转
        return head;
    
    struct ListNode *nexthead=pnext, *pcur=head, *temp=NULL; 
    while(pcur != pnext) //前面k个元素以此翻转
    {
        temp=pcur->next;
        pcur->next = nexthead;
        nexthead=pcur;
        pcur=temp;
    }
    
    return nexthead;
}

struct ListNode* reverseKGroup(struct ListNode* head, int k) {
    if(head==NULL || head->next==NULL || k<=1)
    {
        return head;
    }
    
    struct ListNode dummy={.next=head}; //设置dummy首结点
    struct ListNode *pcur=&dummy;
    
    while(pcur) //从前往后以此翻转k个元素
    {
        pcur->next = reverseList(pcur->next, k); //翻转前k个元素
        for(int i=0; pcur && i<k; ++i) //前进k个元素
        {
            pcur=pcur->next;
        }
    }
    
    return dummy.next;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值