我的LeetCode代码仓:https://github.com/617076674/LeetCode
原题链接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group/description/
题目描述:
知识点:链表
思路:LeetCode024——两两交换链表中的节点和LeetCode206——反转链表的结合
我们需要一个反转链表的函数reverseList(),由于题目要求只能使用常数的额外空间,因此我们只能用迭代的方式来实现这个函数。
我们的关键就是找到要反转的链表的头节点和尾节点。
设立虚拟头节点dummyHead和三个指针cur1、cur2、cur3反转链表。
令cur1指向虚拟头节点dummyHead,cur1指向的是待反转链表的前一个节点。
令cur2指向cur1.next,cur2指向的是待反转链表的第一个节点。
根据k值寻找cur3的位置,如果在寻找过程中cur3为null,我们直接返回dummyHead.next,cur3指向的是待反转链表的尾节点。
只要我们能够寻找到不为null的cur3,就一直进行以下循环。
(1)设立临时节点temp记录cur3.next的值。
(2)令cur3.next为null。
(3)反转以cur2为头节点的链表,并将结果作为cur1.next值。更新cur2.next的值为temp。
(4)上述三步实现完一轮反转后更新cur1的值为cur2,cur2的值为temp,根据k值寻找cur3的值。
因为最多要反转n / k个链表,反转每个链表的时间复杂度都是O(k),因此时间复杂度为O(n)级别的。空间复杂度是O(1)级别的。
JAVA代码:
public class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode dummyHead = new ListNode(-1);
dummyHead.next = head;
ListNode cur1 = dummyHead;
if(cur1.next == null || cur1.next.next == null) {
return head;
}
ListNode cur2 = cur1.next;
ListNode cur3 = cur1;
int index = k;
while(index > 0) {
cur3 = cur3.next;
if(cur3 == null) {
return dummyHead.next;
}
index--;
}
while(true) {
ListNode temp = cur3.next;
cur3.next = null;
cur1.next = reverseList(cur2);
cur2.next = temp;
cur1 = cur2;
cur2 = temp;
cur3 = cur1;
index = k;
while(index > 0) {
cur3 = cur3.next;
if(cur3 == null) {
return dummyHead.next;
}
index--;
}
}
}
public ListNode reverseList(ListNode head) {
ListNode dummyHead = new ListNode(-1);
dummyHead.next = head;
ListNode cur1 = dummyHead;
if(cur1.next == null || cur1.next.next == null) {
return head;
}
ListNode cur2 = cur1.next;
ListNode cur3 = cur2.next;
while(cur3 != null) {
cur2.next = cur3.next;
ListNode temp = cur1.next;
cur1.next = cur3;
cur3.next = temp;
cur3 = cur2.next;
}
return dummyHead.next;
}
}
LeetCode解题报告: