[力扣c语言实现]25. k个一组翻转链表

25. k个一组翻转链表

原题目连接

1. 题目描述

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

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

示例 :

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

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

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

说明 :

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

2.代码如下

/**
* Definition for singly-linked list.
* struct ListNode {
*     int val;
*     struct ListNode *next;
* };
*/
struct ListNode *reverseList(struct ListNode*start,struct ListNode*end,int k)struct ListNode* reverseKGroup(struct ListNode* head, int k) {
    //思路:先写一个能够逆转链表的函数,将链表分成k段分别排序在串起来即可
     typedef struct ListNode list;
    list **lists;
    
    list* p = head;
    list *plast;
    int size = 0;
    if(head == NULL)
    {
        return NULL;
    }
    while(p!=NULL)
    {
        size++;
        p = p->next;
    }
    if(size<k)//链表长度小于k时不用逆转直接返回
    {
        return head;
    }
    int temp = size%k;//判断是否正好能分成k段
    int num = size/k;//分成k段
    if(temp>0)//有余留结点
    {
        int KMORE = num*k;
        plast = head+KMORE;//指向不能单独划分成段的尾部结点的头
    }
    for(int i=0 ;i<num;i++)
    {
        
        *(lists+i) = reverseList(head+i*k,head+(i+1)*k-1,k);
    }
    for(int i = 0 ;i < num-1;i++)
    {
        int temp = i+k;
        *(lists+temp-1)->next = *(lists+temp);
    }
    if(plast!=NULL)
    {
        *(lists+num*k-1)->next = plast;
    }
    return *lists;
}

struct ListNode *reverseList(struct ListNode*start,struct ListNode*end,int k)
{
    typedef struct ListNode list;
    list**lists;
    list *p = start;
    
    for(int i=0;i<k;i++)
    {
        *(lists+i) = start+i;
    }
    list *p1 = start;
    list *p4 = end;
    for(int i = k;i>0;i--)
    {
        *(lists+i)->next = *(lists+i-1);
    }
    return *(lists+k);
}
```c

猜你喜欢

转载自blog.csdn.net/dengwodaer/article/details/90139660