leetcode25.K个一组翻转链表——学习笔记

题目:力扣icon-default.png?t=LA92https://leetcode-cn.com/problems/reverse-nodes-in-k-group/

/**
 * 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 {
    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode prev = null;
        ListNode cur = head;
        ListNode next = null;
        ListNode check = head;
        int canProceed = 0;
        int count = 0;
        while (canProceed < k && check != null) {
            check = check.next;
            canProceed++;
        }
        if (canProceed == k) {
            while (count < k && cur != null) {
                next = cur.next;
                cur.next = prev;
                prev = cur;
                cur = next;
                count++;
            }
            if (next != null) {
                head.next = reverseKGroup(next, k);
            }
            return prev;
        } else {
            return head;
        }
    }
}

代码作者:Angus-Liu 

 思路:虽然做l过leetcode24.两两交换链表中的节点,但是我拿到这道题还是比较懵的。我也是学习了评论区里面的大佬的代码,一句一句代码去掰开来学习。主要是卡在一次交换多个节点的时候,整不明白如何去“翻转”了。大致上的思路和leetcode24.两两交换链表中的节点是差不太多的,这里不再赘述。这里提一提leetcode24与leetcode25的主要区别——需要翻转的节点个数不确定,24题中只要求交换两个节点,但是25题中需要交换的节点不确定。可能是奇数,可能是偶数,若为奇数则中间的节点不需要翻转。

言语表述过于生涩,我做了个视频放在下方。举例说明,当k=3时,翻转的详细过程。(由于技术原因,导致动画移动的效果并不是我想要的,导致指针移动时会比较奇怪。请忽略指针移动的过程,关注移动后的结果就好。)

leetcode25.K 个一组翻转链表 翻转链表思路

1.声明变量。prev用于指向已经完成翻转的链表的头部;cur用于指向翻转操作的位置;next用于存储下一次翻转开始的位置;check用于检测当前链表长度是否符合翻转条件;canProceed用于存储部分链表长度(上限为k);count用于存储每次翻转需要翻转节点的个数。

ListNode prev = null;
ListNode cur = head;
ListNode next = null;
ListNode check = head;
int canProceed = 0;
int count = 0;

2.检查够不够长。用check去检查,用canProceed去记录。

while (canProceed < k && check != null) {
    check = check.next;
    canProceed++;
}

3.当canProceed=k时表示当前链表长度符合“翻转”的条件,下面则进行翻转;若长度不符合条件,则将后续的链表不需要处理直接返回即可。用while控制需要翻转节点的个数,具体翻转的过程见上面的视频。(强烈建议去看视频,以下是文字表述:找到需要翻转的位置,用next存着后续的链表,然后通过cur对其进行修改,最后会分出一条以prev为头指针翻转完成的链。head仍然在最初节点的位置,若next不为空则表示后续链表可能还需要翻转,则再递归调用reverseKGroup方法。将反转好的链表返回,即返回头指针prev。)以此类推,一直到最后,一定会有链表长度不合符条件的时候,那时候执行else中的return head,因此else中的语句也算是递归调用的出口。

if (canProceed == k) {
    while (count < k && cur != null) {
        next = cur.next;
        cur.next = prev;
        prev = cur;
        cur = next;
        count++;
    }
    if (next != null) {
        head.next = reverseKGroup(next, k);
    }
    return prev;
} else {
    return head;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hokachi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值