Topic
- Linked List
Description
https://leetcode.com/problems/reverse-nodes-in-k-group/
Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.
k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes, in the end, should remain as it is.
Follow up:
- Could you solve the problem in
O(1)
extra memory space? - You may not alter the values in the list’s nodes, only nodes itself may be changed.
Example 1:
Input: head = [1,2,3,4,5], k = 2
Output: [2,1,4,3,5]
Example 2:
Input: head = [1,2,3,4,5], k = 3
Output: [3,2,1,4,5]
Example 3:
Input: head = [1,2,3,4,5], k = 1
Output: [1,2,3,4,5]
Example 4:
Input: head = [1], k = 1
Output: [1]
Constraints:
- The number of nodes in the list is in the range
sz
. 1 <= sz <= 5000
0 <= Node.val <= 1000
1 <= k <= sz
Analysis
方法一:递归法,简洁但空杂不是O(1)。
方法二:迭代法,复杂但空杂是O(1)(用了一堆指针,正是个针线活)
Submission
import com.lun.util.SinglyLinkedList.ListNode;
public class ReverseNodesInKGroup {
// 方法一:递归法
public ListNode reverseKGroup1(ListNode head, int k) {
if (k < 2 || head == null)
return head;
int count = 0;
ListNode tail = head;
while (tail != null && k != count) {
count++;
tail = tail.next;
}
if (count == k) {
ListNode newHead = reverseKGroup1(tail, k);
while (count-- > 0) {
ListNode next = head.next;
head.next = newHead;
newHead = head;
head = next;
}
return newHead;
}
return head;
}
// 方法二:迭代法
public ListNode reverseKGroup2(ListNode head, int k) {
if (k < 2 || head == null)
return head;
ListNode fakeHead = new ListNode(-1);
ListNode tail = fakeHead, secondTail = head, secondHead = head;
while(true) {
int count = 0;
while (secondHead != null && k != count) {
count++;
secondHead = secondHead.next;
}
if(k == count) {
ListNode newHead = secondHead;//null;
while(count-- > 0) {
ListNode next = head.next;
head.next = newHead;
newHead = head;
head = next;
}
tail.next = newHead;
tail = secondTail;
head = secondHead;
secondTail = head;
}else
break;
}
return fakeHead.next;
}
}
Test
import static org.junit.Assert.*;
import static com.lun.util.SinglyLinkedList.*;
import org.junit.Test;
public class ReverseNodesInKGroupTest {
@Test
public void test() {
ReverseNodesInKGroup obj = new ReverseNodesInKGroup();
assertTrue(areTwoListEqual(obj.reverseKGroup1(ints2List(1, 2, 3), 3), //
ints2List(3, 2, 1)));
assertTrue(areTwoListEqual(obj.reverseKGroup1(ints2List(1, 2, 3, 4, 5), 2), //
ints2List(2, 1, 4, 3, 5)));
assertTrue(areTwoListEqual(obj.reverseKGroup1(ints2List(1, 2, 3, 4, 5), 3), //
ints2List(3, 2, 1, 4, 5)));
assertTrue(areTwoListEqual(obj.reverseKGroup1(ints2List(1, 2, 3, 4, 5), 1), //
ints2List(1, 2, 3, 4, 5)));
assertTrue(areTwoListEqual(obj.reverseKGroup1(ints2List(1), 1), //
ints2List(1)));
}
@Test
public void test2() {
ReverseNodesInKGroup obj = new ReverseNodesInKGroup();
assertTrue(areTwoListEqual2(obj.reverseKGroup2(ints2List(1, 2, 3), 2), //
ints2List(2, 1, 3)));
assertTrue(areTwoListEqual2(obj.reverseKGroup2(ints2List(1, 2, 3), 3), //
ints2List(3, 2, 1)));
assertTrue(areTwoListEqual2(obj.reverseKGroup2(ints2List(1, 2, 3, 4, 5), 2), //
ints2List(2, 1, 4, 3, 5)));
assertTrue(areTwoListEqual2(obj.reverseKGroup2(ints2List(1, 2, 3, 4, 5), 3), //
ints2List(3, 2, 1, 4, 5)));
assertTrue(areTwoListEqual2(obj.reverseKGroup2(ints2List(1, 2, 3, 4, 5), 1), //
ints2List(1, 2, 3, 4, 5)));
assertTrue(areTwoListEqual2(obj.reverseKGroup2(ints2List(1), 1), //
ints2List(1)));
assertTrue(areTwoListEqual2(obj.reverseKGroup2(ints2List(1, 2, 3, 4, 5, 6), 2), //
ints2List(2, 1, 4, 3, 6, 5)));
}
}