今天是2020年5月16日,星期六。
題目描述
給你一個鏈表,每 k 個節點一組進行翻轉,請你返回翻轉後的鏈表。
k 是一個正整數,它的值小於或等於鏈表的長度。
如果節點總數不是 k 的整數倍,那麼請將最後剩餘的節點保持原有順序。
示例:
給你這個鏈表:1->2->3->4->5
當 k = 2 時,應當返回: 2->1->4->3->5
當 k = 3 時,應當返回: 3->2->1->4->5
說明:
你的算法只能使用常數的額外空間。
你不能只是單純的改變節點內部的值,而是需要實際進行節點交換。
題目思路
本題目是一道鏈表相關的題目,將節點每k個分爲一組,最後剩餘的節點個數不足k個不在處理。
鏈表題目中通常設置一個「虛擬頭節點」就可以很好的解決一些問題。本題目我們也設置一個虛擬頭結點。在遍歷過程中,經過k個節點,就交給單獨的方法buildList
去處理,這樣我們只需要每次遍歷,將逆序的過程交給單獨的方法去處理即可。
注意:小編的這個代碼並不是最優解法,時間上還是消耗比較多的,但是理解起來比較好理解。
參考代碼
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
if (head == null) {
return null;
}
ListNode fast = head;
// 設置一個虛擬頭結點
ListNode newHead = new ListNode(-1);
ListNode currentNode = newHead;
while (true) {
List<ListNode> listNodes = new ArrayList<>(k);
for (int i = 1; i <= k; i++) {
if (fast != null) {
ListNode node = new ListNode(fast.val);
node.next = fast.next;
listNodes.add(node);
fast = fast.next;
} else {
break;
}
}
if (fast != null) {
currentNode = buildList(listNodes, currentNode);
} else {
if (listNodes.size() == k) {
currentNode = buildList(listNodes, currentNode);
} else {
for (int i = 0; i < listNodes.size(); i++) {
currentNode.next = listNodes.get(i);
currentNode = currentNode.next;
}
}
currentNode.next = null;
break;
}
}
return newHead.next;
}
private ListNode buildList(List<ListNode> listNodes, ListNode currentNode) {
int size = listNodes.size();
for (int i = size - 1; i >= 0; i--) {
currentNode.next = listNodes.get(i);
currentNode = currentNode.next;
}
return currentNode;
}
}