題目地址:
https://www.lintcode.com/problem/reverse-nodes-in-k-group/description
給定一個鏈表,再給定一個數,要求個個翻轉鏈表。若不足個則不翻轉。
思路是另開一個專門的函數用於翻轉prev接下來的個節點,同時返回翻轉後的個節點的最後一個,這樣就可以以這最後一個節點作爲prev繼續做翻轉;若不足個則返回null。很顯然一開始的prev就設置爲dummy node接在head前面即可。至於如何翻轉個節點,方法是將這個節點的最後一個節點與之後的節點斷開,然後做翻轉,然後再將翻轉後的個節點的最後一個連到後面去,重新接起來。代碼如下:
public class Solution {
/**
* @param head: a ListNode
* @param k: An integer
* @return: a ListNode
*/
public ListNode reverseKGroup(ListNode head, int k) {
// write your code here
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode prev = dummy;
while ((prev = reverseK(prev, k)) != null) {
}
return dummy.next;
}
private ListNode reverseK(ListNode prev, int k) {
// prev -> n1 -> n2 -> ... -> nk -> tail
ListNode nk = prev;
for (int i = 0; i < k; i++) {
nk = nk.next;
if (nk == null) {
return null;
}
}
// 找到要翻轉的最後一個節點的後面一個節點,然後斷開
ListNode tail = nk.next;
nk.next = null;
// 記錄一下翻轉後的k個節點中的最後一個節點,也就是翻轉前的第一個節點
ListNode n1 = prev.next;
prev.next = reverse(prev.next);
// 連上去
n1.next = tail;
return n1;
}
private ListNode reverse(ListNode head) {
ListNode prev = null;
while (head != null) {
ListNode tmp = head.next;
head.next = prev;
prev = head;
head = tmp;
}
return prev;
}
}
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
時間複雜度,空間。