编程导航算法通关村第二关 | 黄金挑战之K个一组反转

K个一组反转

先来看下LeetCode25这道题目描述:
给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。

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

你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
编程导航算法通关村第二关 | 黄金挑战之K个一组反转_第1张图片
思路:
① 既然给定了k个一组,那我们不妨先找出这条链表中有多少个这样的组,具体方法为:遍历这条链表得到len个结点数,然后n = len / k即可得到有多少个这样的组
② 然后对n个组进行循环,每个循环做的就是翻转组内的结点
③ 那么翻转操作用什么方法呢,可以用头插法,由于头插法每次改变的只有一个节点的顺序,所以需要再用一个子循环嵌套组内循环
先来看代码:

ListNode* reverseKGroup(ListNode* head, int k) {
    ListNode* p = head;
    
    ListNode* ans= (ListNode*)malloc(sizeof(ListNode));
    ans->next = head;
    
    ListNode* pre = ans;
    // 统计结点个数
    int len = 0;
    while(p != NULL) {
        len++;
        p = p->next;
    }
    int n = len / k;
    p = head;
    // 外层循环,翻转组内结点
    for(int i = 0; i < n; i ++) {
    	// 组内结点依次头插
        for(int j = 0; j < k - 1; j ++) {
            ListNode* q = p->next;
            p->next = p->next->next;
            q->next = pre->next;
            pre->next = q;
        }
        // 组内翻转结束时,p指向的是当前组最后一个结点
        // 让pre指向p,也就是下一组的前向结点
        pre = p;
        p = p->next;
    }
    return ans->next;
}

你可能感兴趣的:(算法)