LeetCode 25. K 个一组翻转链表

题目

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

示例 :

给定这个链表:1->2->3->4->5

当 k = 2 时,应当返回: 2->1->4->3->5

当 k = 3 时,应当返回: 3->2->1->4->5

说明 :

  • 你的算法只能使用常数的额外空间。

  • 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

思路

用的是精选题解的思路 因为有图 整个过程解释的非常详细。这道题比较难 在注释中我将每一步的作用都详细的写上了

image
image

源代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public ListNode reverseKGroup(ListNode head, int k) {
    ListNode dummy = new ListNode(0);
    dummy.next = head;

    ListNode pre = dummy;
    ListNode end = dummy;

    while (end.next != null) {
        for (int i = 0; i < k && end != null; i++) end = end.next;
        if (end == null) break;
        ListNode start = pre.next;
        //提前保存下一次要反转的链表部分的第一个节点
        ListNode next = end.next;
        //分割本次反转与为即将将要进行反转的元素
        end.next = null;
        //reverse(start)返回的是本次反转后的最后一个节点
        //pre初始为NULL pre.next = 本次反转最后一个节点位置 为下一次反转做准备 start = pre.next 因为上面有start = pre.next 所以现在start的位置为反转后部分的最后一个节点
        pre.next = reverse(start);
        //将反转后最后一个节点与还未反转部分的第一个节点相连接
        start.next = next;
        //为下一次反转设置前趋节点
        pre = start;
        //为下一次反转设置end节点 以便下一次反转通过end来确定下次反转的结束节点所在位置(那个for循环end = end.next)
        end = pre;
    }
    return dummy.next;
}

private ListNode reverse(ListNode head) {
    ListNode pre = null;
    ListNode curr = head;
    while (curr != null) {
        ListNode next = curr.next;
        curr.next = pre;
        pre = curr;
        curr = next;
    }
    return pre;
}

你可能感兴趣的:(LeetCode 25. K 个一组翻转链表)