原文:
解答一:歸併排序(遞迴法)
題目要求時間空間複雜度分別為o(nlogn)o(nlogn)和o(1)o(1),根據時間複雜度我們自然想到二分法,從而聯想到歸併排序;
對陣列做歸併排序的空間複雜度為 o(n)o(n),分別由新開闢陣列o(n)o(n)和遞迴函式呼叫o(logn)o(logn)組成,而根據鍊錶特性:
陣列額外空間:鍊錶可以通過修改引用來更改節點順序,無需像陣列一樣開闢額外空間;
遞迴額外空間:遞迴呼叫函式將帶來o(logn)o(logn)的空間複雜度,因此若希望達到o(1)o(1)空間複雜度,則不能使用遞迴。
通過遞迴實現鍊錶歸併排序,有以下兩個環節:
分割 cut 環節: 找到當前鍊錶中點,並從中點將鍊錶斷開(以便在下次遞迴 cut 時,鍊錶片段擁有正確邊界);
我們使用 fast,slow 快慢雙指標法,奇數個節點找到中點,偶數個節點找到中心左邊的節點。
找到中點 slow 後,執行 slow.next = none 將鍊錶切斷。
遞迴分割時,輸入當前鍊錶左端點 head 和中心節點 slow 的下乙個節點 tmp(因為鍊錶是從 slow 切斷的)。
cut 遞迴終止條件: 當head.next == none時,說明只有乙個節點了,直接返回此節點。
合併 merge 環節: 將兩個排序鍊錶合併,轉化為乙個排序鍊錶。
雙指標法合併,建立輔助listnode h 作為頭部。
設定兩指標 left, right 分別指向兩鍊錶頭部,比較兩指標處節點值大小,由小到大加入合併鍊錶頭部,指標交替前進,直至新增完兩個鍊錶。
返回輔助listnode h 作為頭部的下個節點 h.next。
時間複雜度 o(l + r),l, r 分別代表兩個鍊錶長度。
當題目輸入的 head == none 時,直接返回none。
class solutionlistnode tmp = slow.next;
slow.next = null;
listnode left = sortlist(head);
listnode right = sortlist(tmp);
listnode h = new listnode(0);
listnode res = h;
while (left != null && right != null) else
h = h.next;
}h.next = left != null ? left : right;
return res.next;
}}
鍊錶排序Sort List(歸併)
題目 sort a linked list in o nlog n time using constant space complexity.因為題目要求複雜度為o nlogn 故可以考慮歸併排序的思想。歸併排序的一般步驟為 1 將待排序陣列 鍊錶 取中點並一分為二 2 遞迴地對左半部分進行歸併排序...
鍊錶排序(sort list)
1 要求 sort a linked list in o n log n time using constant space complexity.2 思路 因為題目要求複雜度為o nlogn 故可以考慮歸併排序的思想。歸併排序的一般步驟為 1 將待排序陣列 鍊錶 取中點並一分為二 2 遞迴地對左半...
148 Sort List (歸併實現鍊錶排序)
sort a linked list in o n log n time using constant space complexity.常見排序方法有很多,插入排序,選擇排序,堆排序,快速排序,氣泡排序,歸併排序,桶排序等等。它們的時間複雜度不盡相同,而這裡題目限定了時間必須為o nlgn 符合要...