題目描述:給定一個鏈結串列的頭節點 head 和一個非負整數 k,將整個鏈結串列向右旋轉 k 個位置,並返回旋轉後的頭節點。
解題思路:
旋轉鏈結串列的關鍵觀察:向右旋轉 k 次,等同於把串列最後 k % n 個節點移到最前面(n 為串列長度)。若 k % n == 0,串列不變。
步驟如下:
n,同時把尾節點的 next 指向頭節點,形成環狀鏈結串列。n - k%n - 1 個位置(從 0 開始)。也就是說,從頭走 n - k%n - 1 步即可到達新尾節點。next 設為 nullptr,斷開環,即可得到旋轉後的串列。此方法只需兩次走訪,時間複雜度為 O(n),空間複雜度為 O(1)。
時間複雜度:O(n) — 第一次走訪計算長度需 O(n);第二次走訪找新尾節點最多再走 n-1 步,同樣是 O(n)。整體為線性時間。
空間複雜度:O(1) — 只使用常數個指標變數(tail、newTail、newHead),不需要額外的資料結構。
1. If head is null, head.next is null, or k == 0, return head as-is. 2. Traverse the list to find its length n and the tail node. 3. Compute effective_k = k % n. If effective_k == 0, return head. 4. Connect tail.next = head to form a circular list. 5. Walk (n - effective_k - 1) steps from head to find the new tail node. 6. Set newHead = newTail.next. 7. Set newTail.next = null to break the circle. 8. Return newHead.
方法一:快慢指標(雙指標)
使用快慢兩個指標,讓快指標先走 k % n 步,然後快慢指標同時前進直到快指標抵達尾節點。此時慢指標的下一節點即為新頭節點。時間複雜度 O(n),空間複雜度 O(1)。無需成環,但需要兩次走訪且邏輯稍複雜。
方法二:轉換為陣列
將鏈結串列所有節點存入 vector,用取餘計算旋轉後的起始索引,重新串連節點。時間複雜度 O(n),空間複雜度 O(n),實作直觀但不符合串列操作精神,且額外空間較多。