《算法通关村第二关-黄金挑战》k个一组的链表反转

      LeetCode25 描述:给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。你不能更改节点中的值,只能更改节点本身。

     方法一:

      首先,因为要分组反转,我们就一组一组的处理,同时为了好处理头结点,我们新建一个虚拟头结点。为了方便循环,我们可以先遍历一遍数组,统计一下元素数量len,确定要分几组n=len/k。然后我们可以发现,对每个要反转的组,其实都可以采用,指定区间反转的思路在循环中对每个组单独进行反转。

实现代码:

  public ListNode reverseKGroup (ListNode head, int k) {
        // write code here
        ListNode res = new ListNode(-1);
        res.next = head;
        ListNode cur = head;
 
        int len = 0; //链表长度
        while (cur != null) {
            len++;
            cur = cur.next;
        }
 
        int n = len / k; //链表分组
 
        cur = head;
        ListNode pre = res;
 
        for (int i = 0; i < n; i++) { //要反转几组
 
            for (int j = 0; j < k - 1; j++) { //每组反转几次
                ListNode next = cur.next;
                cur.next = next.next;
                next.next = pre.next;
                pre.next = next;
 
            }
            pre = cur; //为下一组反转作准备
            cur = cur.next;
 
        }
 
        return res.next;
    }

 

方法二:穿针引线法

    因为要分组反转,我们可以将每个要反转的区间先拆分出来,单独反转然后再拼接回去。和前面一样,我们先建立一个虚拟节点,方便处理头节点,之后我们直接遍历,根据是否为K个找到四个关键位置,并用变量pre、start、end和next标记。
pre:要反转区间的前一个节点
start:要反转区间的开始节点。
end:要反转区间的结束节点。
next:要反转区间的下一个节点。
    public ListNode reverseKGroup (ListNode head, int k) {
        // write code here
        ListNode res = new ListNode(-1);
        res.next = head;
        ListNode pre = res, end = res;

        //找到要处理的区间的末尾
        while (end != null) {
            for (int i = 0; i < k && end != null; i++) {
                end = end.next;
            }
            if (end == null) {
                break;
            }

            //将要处理的区间裁剪下来
            ListNode next = end.next;
            ListNode start = pre.next;
            end.next = null; //切断链表

            reverList(start);//反转之后end变成了头节点,start变成了尾节点
            //将反转的区间缝补回去
            pre.next = end;
            start.next = next;

            pre = end = start; //为下一组的反转作准备

        }

        return res.next;
    }

    //反转链表的方法
    public ListNode reverList(ListNode head) {
        ListNode pre = null;
        ListNode cur = head;
        ListNode next = null;
        while (cur != null) {
            next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值