25. K 个一组翻转链表
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
进阶:
你可以设计一个只使用常数额外空间的算法来解决此问题吗?
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
示例 1:
输入:head = [1,2,3,4,5], k = 2
输出:[2,1,4,3,5]
示例 2:
输入:head = [1,2,3,4,5], k = 3
输出:[3,2,1,4,5]
示例 3:
输入:head = [1,2,3,4,5], k = 1
输出:[1,2,3,4,5]
示例 4:
输入:head = [1], k = 1
输出:[1]
提示:
列表中节点的数量在范围 sz 内
1 <= sz <= 5000
0 <= Node.val <= 1000
1 <= k <= sz
解题思路
复用翻转链表时使用到的函数,完成对一组节点的翻转
- 通过遍历链表,找出每组链表的头尾节点,将这段链表从原链表当中切割分离出来,但是要记录下原链表的切割点,为了将翻转以后的链表重新连接回原来的链表。
- 每次翻转k个节点,当遍历节点时发现当前链表长度不足k了,说明这是最后一段不足k的链表,不需要翻转,直接返回即可
代码
/**
* 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; }
* }
*/
public class Solution {
/**
*
* @param head ListNode类
* @param k int整型
* @return ListNode类
*/
public ListNode reverseKGroup (ListNode head, int k) {
if(head==null||head.next==null||k==1) return head;
ListNode dumpy=new ListNode(-1),pre=dumpy;
dumpy.next=head;
while(true)
{
ListNode h=pre.next,tail=pre.next;
if(tail==null)
return dumpy.next;
for(int i=0;i<k-1;i++)
{
tail=tail.next;
if(tail==null)
return dumpy.next;
}
ListNode npre=tail.next;
tail.next=null;
pre.next=null;
reverseList(h);
pre.next=tail;
h.next=npre;
pre=h;
}
// write code here
}
public ListNode reverseList(ListNode head) {
if (head == null) return null;
ListNode pre = head, next = head.next;
pre.next = null;
while (next != null) {
ListNode nx = next.next;
next.next = pre;
pre = next;
next = nx;
}
return pre;
}
}