题目
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.
Example:
Given this linked list: 1->2->3->4->5
For k = 2, you should return: 2->1->4->3->5
For k = 3, you should return: 3->2->1->4->5
Note:
Only constant extra memory is allowed.
You may not alter the values in the list's nodes, only nodes itself may be changed.
答案
class Solution {
public int list_len(ListNode head) {
int len = 0;
ListNode curr = head;
while(curr != null) {
len++;
curr = curr.next;
}
return len;
}
public ListNode reverseKGroup(ListNode head, int k) {
int len = list_len(head);
int groups = len / k;
if(groups == 0) return head;
// Keep track of start, reverse k guys, start again, until no start is availiable
// prev_group_start: Start of previous group(before reversal), or End of previous group(after reversal)
ListNode prev_group_start = new ListNode(0);
ListNode start = head, ret = null;
while(groups-- > 0) {
// Reverse k nodes starting at start
int cnt = 0;
ListNode curr = start, prev_node = null;
while(cnt < k && curr != null) {
// Store curr.next
ListNode next = curr.next;
// Reverse
curr.next = prev_node;
// for the last guy, set prev_group_start.next to point to it
if(++cnt == k || next == null) {
prev_group_start.next = curr;
if(ret == null) ret = curr;
// Update previous group start
prev_group_start = start;
// Temporarily point to the start of next group(in case next group has less than k elements)
prev_group_start.next = next;
}
prev_node = curr;
curr = next;
}
start = curr;
}
return ret;
}
}