【每日一题】K 个一组翻转链表

本文详细解析了LeetCode中的一道难题——K个一组翻转链表,通过示例解释了算法思路,包括如何控制翻转的子链表长度,如何实际进行节点交换,并提供了完整的Java代码实现。此题要求在常数额外空间复杂度下完成,挑战了链表操作和逻辑控制的能力。
摘要由CSDN通过智能技术生成

本题为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

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

思路:
不要看这是一道hard题,其实只要理解了,用类推的思路还是很简单的。
首先:这题就是翻转链表的变体,只不过不是将整个链表进行翻转,而是每次翻转一串连续的长度为k的子链表;所以,若我们没有遍历到链表的尾结点,则继续进行遍历,遍历的时候用k来控制子链表的长度;在得到子链表后,就是一个翻转链表的操作;用pre来控制该子链表的前一段的最后的一个节点,用end来控制尾结点,start控制头节点,然后进行翻转子链表操作。

详细注解:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        //初始化pre, start和end
        ListNode pre = dummy;
        ListNode start = dummy;
        ListNode end = dummy;
        //当没有遍历到最后一个节点的时候就继续遍历
        while(end.next != null){
            //用k来控制要翻转的子链表的长度
            for(int i = 0; i < k && end != null; i++)
                end = end.next;
            if(end == null)//如果end为空,表示剩余的链表的长度没有达到k,则退出循环
                break;
            //保留下一部分
            ListNode next = end.next;
            end.next = null;//尾结点的下一个节点置空,方便进行翻转操作
            start = pre.next;//子链表的头节点
            pre.next = reverse(start);//翻转之后返回的是翻转后的第一个节点
            start.next = next; //start跑到了子链表的最后
            //重置pre和end
            pre = start;
            end = start;          
        }
        return dummy.next;

    }

    //翻转链表
    public ListNode reverse(ListNode head){
        ListNode pre = null;
        ListNode cur = head;
        while(cur != null){
            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、付费专栏及课程。

余额充值