思路都在代码注释里,就不多说了。
//思路:记录当前要反转的这一截链表的前一个节点和后一个节点,对中间这些节点进行链表反转,然后再把它接回到原来的链表里
public ListNode reverseKGroup(ListNode head, int k) {
//用来记录前一个节点
ListNode pre=new ListNode();
pre.next=head;
//用来记录最终要返回新的 头结点
ListNode res=pre;
int i=0;
ListNode cur=head;
while (cur!=null){
//如果当前这一截链表的长度为k
if (i!=0 && i%k==0){
ListNode tail=cur;
List<ListNode> list = reverse(pre.next, tail);
pre.next=list.get(0);
list.get(1).next=cur;
pre=list.get(1);
}
++i;
cur=cur.next;
}
//要考虑cur遍历到null的时候,可能还有最后一截链表需要反转
if (i%k==0){
List<ListNode> list = reverse(pre.next, null);
pre.next=list.get(0);
}
return res.next;
}
//注意:要反转的链表是不包括tail这个节点的,它只是用来判断是否要结束,和原始版本的反转链表的null一个道理
public List<ListNode> reverse(ListNode head,ListNode tail){
ListNode newTail=head;
ListNode pre=null;
ListNode cur=head;
while (cur!=tail){
ListNode next=cur.next;
cur.next=pre;
pre=cur;
cur=next;
}
List<ListNode> res =new ArrayList<>();
//新的头结点
res.add(pre);
//新的尾节点
res.add(newTail);
return res;
}