- 首先,题目有两个特殊输入,即空 或者k=1 该情况只需直接返回即可
 - 下面考虑别的情况:
 
从第一个结点开始遍历
逆置的起点一定是从(n-1)k+1位 到 nk 如 123 k=3 逆置从1 到 3 n=1
由于只有每次遇到k的倍数位时开始逆置,逆置个数为k个,而当出现不满k个的组就不会进行逆置
我们考虑创建一个空的头结点,每次遍历到倍数nk时开始逆置,但是同时需要记录逆置的开始指针,以及所需的指针
例如: 12345 3 用q记录1 从1开始到3 用p记录3 r记录4
q:用于记录每个开始逆置的结点
p:用于记录当前结点情况 为中间或逆置开始 或逆置结束结点
r:用于记录逆置结束位的下一位 ,方便下一次进行逆置
这里采用了i=1记录每个结点情况,是否为 首 中 尾
- 若i%k==1,则令q=到当前位置; 此情况代表p遍历到了第(n-1)k+1位
 - 若i%k==0,p为当前位置 ,r为当前位置的下一位,并开始逆置; 此情况代表p遍历到了nk位
 - 其余情况, p往后移动
 
逆置:
tempHead=p; 注意:逆置结束后 p为新的头结点
(当q不为r时){//头插法
temp=q->next;
q->next=pre->next;
pre->next=q;
q=temp;
}
p=r;(回到i%k为1的情况 q=p;)
pre=tempHead;
当p为空时,要么结点全都接完了,要么位数不够,把剩余结点接入L即可
位数不够时 (n-1)k+2 <= i <= nk
如果(i-1)%k!=0 这里取i-1去取余
pre->next = q; 接入头结点
struct ListNode* reverseKGroup(struct ListNode* head, int k ) {
    // write code here
    
    //特殊情况
    if(k <= 1 || head == NULL){
        return head;
    }
    
    int i = 1;
    //创建一个头结点,便于反转
    struct ListNode* L = (struct ListNode*)malloc(sizeof(struct ListNode));
    L->next = NULL;
    struct ListNode *p,*pre,*q,*r,*tempHead;
    struct ListNode *temp;
    pre = L; 
    p = head; 
    
    while(p){ 
       
        if(i % k == 1){
            q = p;
        }
        
        if(i % k == 0){
            //r指向 p 的下一个 temp 指向 q
            r = p->next;
            tempHead = q;
            //头插法
            while(q!=r){
                temp = q->next;
                q->next = pre->next;
                pre->next = q;
                q = temp;
            }
            p = r;
            pre = tempHead;
            
        }else{
            p = p->next;
        
        }
        i++;
    }
    
    if((i-1) % k != 0){
        pre->next = q;
    }
    return L->next;

京公网安备 11010502036488号