对于之后一旦碰到链表的相关问题都要想到利用递归的方法来解决该问题,因为从本质上来说链表的建立实际上也是递归的建立.
具体代码块如下所示:
/**
* 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) {
if(head==null||head.next==null){
return head;
}
ListNode firstHead=head,firstTail=head,secondHead;
for(int i=1;i<=k-1;i++){
firstTail=firstTail.next;
if(firstTail==null){
return firstHead;
}
}
secondHead = firstTail.next;
firstTail.next=null;
resverse(firstHead);
firstHead.next=reverseKGroup(secondHead,k);
return firstTail;
}
private ListNode resverse(ListNode head){
if(head==null||head.next==null){
return head;
}
ListNode next=head.next;
ListNode newHead=resverse(next);
next.next=head;
head.next=null;
return newHead;
}
}
思想以及代码解释如下所示:
借用上一题的思路,再面对链表的有关题目时,要先考虑能否通过递归的方法来解决此问题,因为链表本身实际上就是通过递归的方法建立起来的,由上一题的思路,可以直接想到可以先进行前k个结点的交换之后对于除前k个结点之外的结点构成的链表递归的调用该方法来解决后续结点的交换问题,最后将后续结点构成的链表插在已经完成交换后的前k个结点的最后面,将组成的链表的头结点输出即可.
注意首先要进行判断该链表是否为空或者该链表是否只有一个结点,如果满足直接将该头结点head输出即可.如果不满足时,为了实现对于前k个结点进行交换,要先将该k个结点截取下来,故而设置一个firstHead以及firstTail分别指向第一个以及第k个结点,之后循环进行k-1次firstTail=firstTail.next令firstTail指向第k个结点,中间也要注意如果firstTail为空表示该段没有k个结点因此不需要交换,直接返回头结点也就是return firstHead;之后令secondHead=firstTail.next来确定下一段链表的头指针以防止丢失下一段链表,令firstTail.next=null使得该k个链表彻底成为单个的链表,之后调用自己定义的resverse()方法来实现此以firstHead为头结点的前k个结点构成的链表的交换即为resverse(firstHead);实现后该链表实际上头结点已经变成了firstTail;之后递归调用方法firstHead.next=reverseKGroup(secondHead,k);在完成了由前k个结点之后的所有结点的链表的交换之后返回交换之后链表的头结点并以该头结点作为前k个结点的链表的尾结点的子节点从而实现两个链表的连接,并完成了该方法,之后将连接后的链表的头结点firstTail输出即可.这种思想其实是对于24题目的一种一般化.
之后是对于方法private ListNode resverse(head);的实现原理实际上也是依靠递归的方法来实现,例如对于k=3时的实例2(1->2->3->4->5)的前k个结点为1->2->3,首先该方法还是要判断该链表是否为空或者只有一个结点,若是则直接返回head接口,若不是则先令ListNode next=head.next;即定义一指针next指向要交换的链表的头结点(1)的下一个结点(即为2),之后递归调用以next为头结点的该链表的后续部分即
ListNode newHead=resverse(next);实现了后续部分的交换(即后续部分变为3->2(next))之后令该后续链表的头结点返回值定义为newHead,此时对于此后续结点中的next结点实际已经成为了尾结点,之后将之前最先的头结点head定义为next的父节点即:next.next=head;此时整个链表就变成了(3->2->1)即完成了整个链表的反转.
至此基于两个由递归思想建立的两个方法reverseKGroup(),reverse()均讲解完毕,也正是基于这两个方法的递归调用从而解决了该问题。
作者:6oofy-mcleandps
链接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group/solution/zai-leetcode-by-6oofy-mcleandps-2mgg/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。