文章标题

来源:互联网 发布:大话西游源码 编辑:程序博客网 时间:2024/05/19 15:41

25 reverse nodes in k groups

题目链接


题意

给一个链表和一个数字k,要求从链表头开始,每次翻转k个节点,若不足k个节点则不翻转

思路

用一个节点指针currentHead指向每次要翻转的k个节点的第一个,另一个节点指针boundary用于向后搜索到要翻转的k个节点后的第一个节点,然后进行k次操作,每次操作中先用temp保存待翻转的第二个节点指针,然后使第一个节点指针的next指向boundary,这就实现了将头节点放到待翻转区域的尾部了,接着表示将待翻转区域的boundary指针指向刚移动的第一个节点指针currentHead,最后将temp赋值给currentHead,也就是将原本的第二个节点指针变成了第一个,如此循环。算法复杂度为O(n)。

递归版本

ListNode* reverseKGroup(ListNode* head, int k) {        if (k == 1)            return head;        ListNode *boundary = head, *temp;        int count = 0;        while (boundary&&count < k) {            boundary = boundary->next;            ++count;        }        if (count == k) {            boundary = reverseKGroup(boundary, k);            while (count--) {                temp = head->next;                head->next = boundary;                boundary = head;                head = temp;            }            head = boundary;        }        return head;    }


非递归版本

/***比递归版本快了。。1ms*/ListNode* reverseKGroup(ListNode* head, int k) {        if (k == 1)            return head;        ListNode *currentHead = head, *boundary = head,            *theNodeToMove, *temp, *lastOfLastKNodes = nullptr, *last;        int count;        bool firstTurn = true;        while (boundary) {            boundary = currentHead;            count = 0;            //用指针boundary找到需要翻转的k个节点之后的第一个节点            while (boundary&&count < k) {                boundary = boundary->next;                ++count;            }            if (count == k) {                last = currentHead;//先保存当前第一个节点指针,后面用于更新lastOfLastKNodes                theNodeToMove = currentHead;                currentHead = boundary;                while (count--) {                    temp = theNodeToMove->next;                    theNodeToMove->next = boundary;                    boundary = theNodeToMove;                    theNodeToMove = temp;                }                if (firstTurn) {//第一遍循环                    firstTurn = false;                    head = boundary;                    lastOfLastKNodes = last;                }                else {                    lastOfLastKNodes->next = boundary;                    lastOfLastKNodes = last;                }            }        }        return head;    }


难点

  1. k个节点指针翻转时循环k次
  2. 非递归版本需要每次翻转完k个节点后需要用lastOfLastKNodes记录翻转后的最后一个节点,也就未翻转时的第一个节点currentHead,如果是第一遍循环只需记录,否则必须先将已有的lastOfLastKNodes的next指向本次翻转后的第一个节点,然后再改变lastOfLastKNodes的值
原创粉丝点击