算法——K 个一组翻转链表

给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例:
给你这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
leetcode

利用四个指针,分别指向需要反转一段区间的头尾节点,以及头节点的前一节点,尾节点的下一节点,进行反转,不断迭代。

/**
 * created by lippon
 */
class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {

        // 声明四个节点
        ListNode a, b , c, d, dummy;

        // 排除特殊情况
        if(head == null || head.next == null || k == 1) return head;

        // 实例化虚拟头节点,用于返回结果
        dummy = new ListNode(0);
        dummy.next = head;

        // 四个节点置位
        a = dummy;
        b = dummy.next;
        c = dummy;
        d = dummy.next;

        // 若末尾节点为null则退出循环 
        while(d != null){

            // 将cd节点送到需要交换的尾部
            for(int i = 0; i < k; i++){
                // 不足k, 则直接返回结果
                if(d == null) return dummy.next;
                c = c.next;
                d = d.next;
            }

            // 获取已经交换段的尾节点, 重新置位
            a = reverse(a, b, c, d);
            b = a.next;
            c = a;
            d = a.next;
        }

        // 返回头节点
        return dummy.next;  
    }

    // 交换函数,a节点的下一个节点为需要交换段的头节点, b为需要交换段的尾部节点
    // 为需要交换段的尾部节点, d为需要交换段的尾节点的下一节点
    public ListNode reverse(ListNode a, ListNode b, ListNode c, ListNode d){
        // 双指针用于反转
        ListNode i = b, j = b.next;

        // 反转该段链表
        while(j != d){
            ListNode temp = j.next;
            j.next = i;
            i = j;
            j = temp;
        }

        // 将完成交换的头尾节点连上
        a.next = c;
        b.next = d;

        // 返回末尾节点
        return b;
    }
}
原文地址:https://www.cnblogs.com/lippon/p/14117721.html