【leetcode】25. Reverse Nodes in k-Group

题目说明

https://leetcode-cn.com/problems/reverse-nodes-in-k-group/description/
给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序。

解法1


首先遍历链表,记录结点个数,当满足个数等于k时,开始进行反转,反转完成后,个数重新计数。
假设n为k区间中需要反转的第一个结点,n+k为最后一个结点。使用pre指向[n,n+k]区间的前一个结点(即n-1),使用cur进行遍历,满足条件时,cur指向n+k这个结点
反转方法:对[n,n+k]进行遍历,每次将后一个结点指向前一个结点。[n,n+k]这个区间进行反转操作后,还需要使[n,n+k]这个区间的结点能够与两边串联起来:将pre指向n+k这个结点,并且n这个结点需要指向n+k+1这个结点。

/*
 * 时间复杂度:O(n)
 */
ListNode* reverseKGroup(ListNode* head, int k) {
    ListNode *dummy = new ListNode(0);
    dummy->next = head;
    ListNode *pre = dummy;
    ListNode *pre_in = NULL; //[n,n+k]区间操作时的前结点
    ListNode *cur = NULL;    //遍历整个结点
    ListNode *cur_in = NULL; //[n,n+k]区间操作时的当前结点
    ListNode *next = NULL;   //[n,n+k]区间操作时的下一结点
    ListNode *first = NULL;  //记录n这个结点
    int count = 0;

    cur = pre->next;
    while(cur){
        count ++;
        if (count == k){
            pre_in = pre;
            cur_in = pre->next;
            first = cur_in;
            for (int i = 0; i < k; i ++){//反转操作
                next = cur_in->next;
                cur_in->next = pre_in;
                pre_in = cur_in;
                cur_in = next;
            }
            pre->next = pre_in;  //pre指向n+k这个结点
            first->next = next;  //n这个结点需要指向n+k+1这个结点
            pre = first;         //移动pre结点到n结点,是为下一个k长度区间的前一个结点
            cur = pre->next;
            count = 0;           //重新计数
            continue;
        }
        cur = cur->next;
    }
    return dummy->next;
}

解法2


两次遍历,第一次得到链表长度。
第二次遍历每次进行k区间的反转。
反转的方法:
假设[n,n+k]这个区间进行反转,对第i(n<=i<=n+k)个结点进行反转时将n+i指向i-1,n-1指向i,n指向i+1,而其他点不需要变动

/*
 * 时间复杂度:O(n)
 */
ListNode* reverseKGroup(ListNode* head, int k) {
    ListNode *dummy = new ListNode(0);
    dummy->next = head;
    ListNode *pre = dummy;
    ListNode *cur = pre->next;
    ListNode *next = NULL;
    int num = 0;

    while(cur){
        cur = cur->next;
        num ++;
    }
    while(num >= k){
        cur = pre->next;
        next = cur->next;
        for (int i = 1; i < k; i ++){
            cur->next = next->next;
            next->next = pre->next;
            pre->next = next;
            next = cur->next;
        }
        num -= k;
        pre = cur;
    }
    return dummy->next;
}
posted @ 2018-09-04 01:48  JESSET  阅读(134)  评论(0编辑  收藏  举报