leetcode 25. K 个一组翻转链表

@(labuladong的算法小抄)[链表]

leetcode 25. K 个一组翻转链表

题目描述

在这里插入图片描述

解题思路

参考:labuladong的算法小抄P289

迭代+递归,O(k)空间复杂度

class Solution {
	//定义:翻转从head开始的k个元素,返回翻转后的头结点
    public ListNode reverseKGroup(ListNode head, int k) {
        if (head == null) return null;
        /* 区间[a, b)包含k个待翻转的元素 */
        ListNode a = head, b = head;
        for (int i = 0; i < k; i++) {
            /* base case,不足k个,不需要翻转,直接返回head */
            if (b == null) return head;
            b = b.next;
        }
        /* 翻转区间[a, b)内的k个元素 */
        ListNode newHead = reverse(a, b);
        /* 翻转后,a变为新链表的尾节点,因此和后面的链表连接 */
        a.next = reverseKGroup(b, k);
        return newHead;
    }

    /* 翻转区间[a, b)内的k个元素,返回翻转后的头结点 */
    private ListNode reverse(ListNode a, ListNode b) {
        /* 用头插法,pre始终指向新链表的头结点,初始新链表为空 */
        ListNode pre = null;
        /* 不断将cur所指的节点插到新链表的头部 */
        ListNode cur = a;

        while (cur != b) {
            ListNode next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }
}

纯迭代,O(1)空间复杂度

class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        if (head == null) return null;
        /* hair表示空白的首节点 */
        ListNode hair = new ListNode();
        hair.next = head;
        /* preTail表示上一段链表翻转后的尾节点 */
        ListNode preTail = hair;
        while (head != null) {
            /* 区间[a, b)包含k个待翻转的元素 */
            ListNode a = head, b = head;
            for (int i = 0; i < k; i++) {
                /* base case,不足k个,不需要翻转,直接返回 */
                if (b == null) return hair.next;
                b = b.next;
            }
            /* 翻转区间[a, b)内的k个元素 */
            ListNode newHead = reverse(a, b);
            /* 将上一段链表的尾节点接过来 */
            preTail.next = newHead;
            /* 将a和下一段链表接上 */
            a.next = b;
            /* 翻转后,a就是当前新链表的尾节点 */
            preTail = a;
            /* 继续从下一段链表开始 */
            head = b;
        }
        return hair.next;
    }

    /* 翻转区间[a, b)内的k个元素,返回翻转后的头结点 */
    private ListNode reverse(ListNode a, ListNode b) {
        /* 用头插法,pre始终指向新链表的头结点,初始新链表为空 */
        ListNode pre = null;
        /* 不断将cur所指的节点插到新链表的头部 */
        ListNode cur = a;

        while (cur != b) {
            ListNode next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值