一. 题目

二. 思路

  • 本质就是分段翻转链表。

  • 保存当前段的前一个节点,比较方便。

三. 代码

class Solution
{
    public ListNode reverseKGroup(ListNode head, int k)
    {
        final ListNode vh = new ListNode();
        vh.next = head;

        int cnt;
        ListNode ph = vh, tail = null;//当前段的头结点的前一个节点和尾巴节点
        while (true)
        {
            cnt = 0;
            ListNode cur = ph.next;//检查是否这段有k个
            while (cur != null && cnt < k)
            {
                ++cnt;
                tail = cur;
                cur = cur.next;
            }
            if (cnt < k) break;

            ListNode pn = tail.next, sh = ph.next;//前一个节点和开始的头
            cur = ph.next;//当前节点
            ph.next = tail;//让上一个节点连到翻转后的头
            ph = sh;//ph下一次就是最初的头
            for (int i = 0; i < k; ++i)
            {
                ListNode ne = cur.next;//当前节点的下一个节点
                cur.next = pn;//当前节点指向前一个节点
                pn = cur;//前一个节点变为当前节点
                cur = ne;//当前节点到达下一个节点
            }
        }

        return vh.next;
    }
}
class Solution
{
    private static class RNode
    {
        ListNode head, tail, NHead;//翻转后当前段的头尾,以及下一段的起点

        public RNode(ListNode head, ListNode tail, ListNode NHead)
        {
            this.head = head;
            this.tail = tail;
            this.NHead = NHead;
        }
    }

    //返回反转后的头和尾巴
    RNode reverse(ListNode cur, int k)
    {
        ListNode ph = cur, pn = null, ne = null;
        for (int i = 0; i < k; i++)
        {
            ne = cur.next;
            cur.next = pn;
            pn = cur;
            cur = ne;
        }

        return new RNode(pn, ph, ne);
    }

    public ListNode reverseKGroup(ListNode head, int k)
    {
        ListNode vh = new ListNode(), pt = vh;//虚拟头以及上一段的尾巴
        while (head != null)
        {
            int cnt = 0;
            ListNode cur = head;
            while (cur != null && cnt < k)
            {
                ++cnt;
                cur = cur.next;
            }

            if (cnt < k)
            {
                pt.next = head;
                break;
            } else
            {
                RNode res = reverse(head, k);
                pt.next = res.head;
                pt = res.tail;
                head = res.NHead;
            }
        }
        return vh.next;
    }
}