(Java)LeetCode-25. 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.
If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.
You may not alter the values in the nodes, only nodes itself may be changed.
Only constant memory is allowed.
For 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
這道題是反轉每k的節點的子鏈,末尾不足k個的不反轉。首先我的想法是每k個節點進棧,然後按照出棧的順序連線起來,則自然反轉,最後不足k個節點,就直接返回首節點。
程式碼方面也參照了上一題的迭代方法,很簡潔。
public ListNode reverseKGroup(ListNode head, int k) { Stack<ListNode> st = new Stack<ListNode>(); ListNode temp = head; for(int i = 0; i < k ; i++){ if(head != null){ st.push(head); }else{ return temp; } head = head.next; } ListNode first = st.pop(); ListNode res = first; for(int i = 0; i<k-1; i++){ first.next = st.pop(); first = first.next; } first.next = reverseKGroup(head,k); return res; }
但是呢,用stack一方面速度較慢,另一方面萬一記憶體溢位就不好玩了,所以我下面採用了另一種方法來反轉。其實連結串列的反轉是一個經典題目,這個過程之前也看到過,這裡只是有一點點的不一樣,即不是反轉全部連結串列,而是一部分一部分的反轉。就單部分反轉來說,思路是一樣的。
思路如下:每次都將原第一個結點之後的那個結點放在頭節點的後面,下圖是原始的單鏈表。
為了反轉這個單鏈表,我們先讓頭結點的next域指向結點2,再讓結點1的next域指向結點3,最後將結點2的next域指向結點1,就完成了第一次交換,順序就變成了Header-結點2-結點1-結點3-結點4-NULL,然後進行相同的交換將結點3移動到結點2的前面,然後再將結點4移動到結點3的前面就完成了反轉。
public ListNode reverseKGroup(ListNode head, int k) {
ListNode root = new ListNode(-1);
root.next = head;
ListNode res = root;
ListNode temp = head;
int i = 0;
while(temp != null){
i++;
temp = temp.next;
}
while(i >= k){
for(int j = 0 ; j < k-1; j++){
ListNode node = root.next;
root.next = head.next;
head.next = root.next.next;
root.next.next = node;
}
root = head;
head = head.next;
i-=k;
}
return res.next;
}