题目:力扣https://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;
}