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

说明:
你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

题目分析

指针指向头部,判断剩余长度是否达到 k。
如果长度足够,则只对前 k 个位置做反转,反转后把剩余部分的连接做好。后续局部的头和尾会发生互换,将指针指向新的局部尾。
不断重复,直到剩余部分不足k个。

Java

public ListNode reverseKGroup(ListNode head, int k) {
    ListNode fake = new ListNode(0, head);
    ListNode cur = fake;
    while (length(cur.next) >= k) {
        ListNode pHead = reverseFirstK(cur.next, k);
        ListNode pTail = cur.next;
        cur.next = pHead;
        cur = pTail;
    }

    return fake.next;
}

private int length(ListNode head) {
    int length = 0;
    while (head != null) {
        head = head.next;
        length++;
    }
    return length;
}

private ListNode reverseFirstK(ListNode head, int k) {
    ListNode pre = null, cur = head;
    while (cur != null && k > 0) {
        ListNode temp = cur.next;
        cur.next = pre;
        pre = cur;
        cur = temp;
        k--;
    }
    head.next = cur;
    return pre;
}

Kotlin

fun reverseKGroup(head: ListNode?, k: Int): ListNode? {
    val fake = ListNode(0)
    fake.next = head
    var cur: ListNode? = fake
    while (length(cur?.next) >= k) {
        val pTail = cur?.next
        val pHead = reverseFirstK(cur?.next, k)
        cur?.next = pHead
        cur = pTail
    }

    return fake.next
}

private fun length(head: ListNode?): Int {
    var length = 0
    var cur = head
    while (cur != null) {
        cur = cur.next
        length++
    }
    return length
}

private fun reverseFirstK(head: ListNode?, k: Int): ListNode? {
    var tail: ListNode? = null
    var cur: ListNode? = head
    var count = k
    while (cur != null && count > 0) {
        val temp = cur.next
        cur.next = tail
        tail = cur
        cur = temp
        count--
    }
    head?.next = cur
    return tail
}

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部