LeetCode:25 K 个一组的翻转链表

81 阅读2分钟

「这是我参与2022首次更文挑战的第17天,活动详情查看:2022首次更文挑战

题目

给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。

k 是一个正整数,它的值小于或等于链表的长度。

如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

进阶:

  • 你可以设计一个只使用常数额外空间的算法来解决此问题吗?
  • 你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

示例 1:

img

输入:head = [1,2,3,4,5], k = 2
输出:[2,1,4,3,5]

示例 2:

img

输入:head = [1,2,3,4,5], k = 3
输出:[3,2,1,4,5]

示例 3:

输入:head = [1,2,3,4,5], k = 1
输出:[1,2,3,4,5]

示例 4:

输入:head = [1], k = 1
输出:[1]

提示:

  • 列表中节点的数量在范围 sz
  • 1 <= sz <= 5000
  • 0 <= Node.val <= 1000
  • 1 <= k <= sz

解题

解题一:分组反转

思路

  1. 当头节点是 null(head==null),或者一个一组(k==1)时,返回头节点
  2. 定义
    • 结果(result)用于返回翻转后的结果
    • 下一个头(nextHead)用于定位下一次翻转头节点
    • 临时尾节点(tempTail)用于连接下一个翻转结果
  3. 循环执行翻转代码,下一个头节点进行遍历
    • 如果满足 k 位,则进行翻转,并且加入结果,临时尾节点后移等于下一个头节点
    • 如果不满足 k 位,则返回结果

代码

/**
 * Definition for singly-linked list.
 */
public class ListNode {
    int val;
    ListNode next;

    ListNode() {
    }

    ListNode(int val) {
        this.val = val;
    }

    ListNode(int val, ListNode next) {
        this.val = val;
        this.next = next;
    }
}

class Solution {

    /**
     * 指定头节点翻转多少位
     * @param head
     * @param k
     * @return
     */
    public static ListNode changeHead(ListNode head, int k) {
        ListNode nextHead = head.next;
        ListNode tail = head;
        for (int i = 0; i < k - 1; i++) {
            tail.next = nextHead.next;
            nextHead.next = head;
            head = nextHead;
            nextHead = tail.next;
        }
        return head;
    }

    public static ListNode reverseKGroup(ListNode head, int k) {
        if (head == null || k == 1) {
            return head;
        }
        ListNode result = null;
        ListNode nextHead = head;
        ListNode tempTail = head;
        while (true) {
            for (int i = 0; i < k; i++) {
                // 遍历列表是否足够 k 个一组
                if (nextHead != null) {
                    nextHead = nextHead.next;
                } else {
                    // 不够一组
                    if (result == null) {
                        return head;
                    } else {
                        return result;
                    }
                }
            }
            ListNode reverseNode = changeHead(head, k);
            if (result == null) {
                result = reverseNode;
            } else {
                tempTail.next = reverseNode;
                tempTail = head;
            }
            head = nextHead;
        }
    }
}

总结

性能分析

  • 执行耗时:0 ms,击败了 100.00% 的 Java 用户
  • 内存消耗:41.4 MB,击败了 5.03% 的 Java 用户