题目:
给你链表的头节点 head
,每 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]
提示:
- 链表中的节点数目为
n
1 <= k <= n <= 5000
0 <= Node.val <= 1000
进阶:你可以设计一个只用 O(1)
额外内存空间的算法解决此问题吗?
题解:
思路:
写一个反转链表,然后使用start来记录需要翻转链表的头部,end来控制断开尾部,以及是否够k个,是否需要继续翻转。pre记录k大小链表前一个,next记录后一个
翻转时将k大小的链表从主链中断开,反转完之后通过pre和next再链接到主链中。
代码:
public ListNode reverse(ListNode head) {
if (head == null || head.next == null){
return head;
}
ListNode preNode = null;
ListNode curNode = head;
ListNode nextNode = null;
while (curNode != null){
nextNode = curNode.next;
curNode.next=preNode;
preNode = curNode;
curNode = nextNode;
}
return preNode;
}
public ListNode reverseKGroup(ListNode head, int k) {
if (head == null || head.next == null){
return head;
}
ListNode dummy=new ListNode(0);
dummy.next=head;
ListNode pre=dummy;
ListNode end=dummy;
while(end.next!=null){
for(int i=0;i<k&&end != null;i++){
end=end.next;
}
if(end==null){
//剩下的不足k个是否需要反转
// ListNode start=pre.next;
// pre.next=reverse(start);
break;
}
ListNode next=end.next;
end.next=null;
ListNode start=pre.next;
pre.next=reverse(start);
start.next=next;
pre=start;
end=start;
}
return dummy.next;
}