刷题的日常-K 个一组翻转链表

49 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第19天,点击查看活动详情

刷题的日常-2022年10月16号

一天一题,保持脑子清爽

K 个一组翻转链表

来自leetcode的 25 题,题意如下:

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

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

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

示例1:

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

image.png

理解题意

通过题意,我们可以将信息整理如下:

  • 题目给定一个链表 和 一个数字 k
  • 要求我们按照k个一组进行翻转
  • 返回翻转过后的链表头节点

做题思路

我们可以在遍历的时候统计遍历过的个数,达到k个之后进行翻转,之后再往后重复这个过程。为了返回头节点,可以开辟一个头节点进行记录。步骤如下:

  • 如果k为1,则不需要翻转,直接返回
  • 开辟一个头节点记录开始位置
  • 开辟快慢指针
  • 循环处理链表,如果没到尾部则继续
  • 到达k个进行翻转,并记录前置后置信息,防止链接丢失
  • 返回虚拟头节点的下一位

代码实现

代码实现如下:

public class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        if (k == 1) {
            return head;
        }
        ListNode idx = head = new ListNode(-1, head);
        ListNode pre = head.next, post = pre;
        int cnt;
        while (post != null) {
            cnt = 0;
            while (++cnt < k) {
                if ((post = post.next) == null) {
                    return head.next;
                }
            }
            ListNode tmpHead = new ListNode(-1), tmp, next = post.next, tail = pre;

            while (pre != post) {
                tmp = pre.next;
                pre.next = tmpHead.next;
                tmpHead.next = pre;
                pre = tmp;
            }
            tmp = tmpHead.next;
            tmpHead.next = post;
            post.next = tmp;
            
            idx.next = tmpHead.next;
            idx = tail;
            idx.next = post = pre = next;
        }

        return head.next;
    }
}

image.png