日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

leetcode 148. Sort List | 148. 排序链表(最优解归并排序,O(1)空间)

發布時間:2024/2/28 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 leetcode 148. Sort List | 148. 排序链表(最优解归并排序,O(1)空间) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目

https://leetcode.com/problems/sort-list/

題解

分析

就鏈表排序問題來說,它的解法可以有好多種。但它的最優解應該只有一種思路,即從下至上的歸并,時間復雜度 O(nlogn),空間復雜度 O(1)。詳見本文的實現。

另外,還有一些其他的方法,例如:

  • 時間復雜度O(n^2)的 冒泡插入
  • 空間復雜度O(n)的 任意額外空間排序,最后再把鏈表重新串起來
  • 時間復雜度O(nlogn),空間復雜度O(logn)的 快排
  • 時間復雜度O(nlogn),空間復雜度O(logn)的從上至下 歸并

最優解(歸并)比較繞,我的辦法是多用幾個變量把中間狀態接住,兩層 while 循環,外層控制 step,內層控制每一小組內的歸并排序,需要注意的是,內層循環中,當前小組的前后組都不要斷掉,所以需要記錄 preTail 和 nextHead,分別表示前一組的終點和后一組的起點,方便前后的銜接。

關于本算法的時間復雜度計算,可以使用 Master 公式:

Master公式

簡介

在編程中,遞歸是非常常見的一種算法,但遞歸相比順序執行或循環程序,時間復雜度難以計算,而master 公式就是用來計算遞歸程序的時間復雜度。

公式

T(N) = aT(N/b) + O(N^d)

  • b:子過程的樣本量
  • a:子過程的計算次數
  • O(N^d):子結果合并的時間復雜度

滿足如上公式的程序,都可以根據master公式計算時間復雜度:

  • log(b,a) > d :時間復雜度為O(N^log(b,a))
  • log(b,a) = d :時間復雜度為O(N^d * logN)
  • log(b,a) < d :時間復雜度為O(N^d)

附草稿

代碼

/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/ class Solution {public ListNode sortList(ListNode head) {int len = 0;ListNode t = head;while (t != null) {t = t.next;len++;}int step = 1;ListNode p1;ListNode p2;ListNode preTail;ListNode nextHead;ListNode newHead = new ListNode();newHead.next = head;while (step <= len) {p1 = newHead.next;preTail = newHead;while (p1 != null) {// - - - 初始化各種位置 - - -// 找好p1,p2位置 注意超出邊界的情況p2 = p1;for (int i = 0; i < step; i++) {if (p2 != null) p2 = p2.next;}if (p2 == null) break;nextHead = p2;for (int i = 0; i < step; i++) {if (nextHead != null) nextHead = nextHead.next;}// - - - 每組排序 - - -// 如果p2=null,說明這組已經有序ListNode tp1 = p1;ListNode tp2 = p2;// 和上一段接上ListNode sortedTail = preTail;if (tp1.val < tp2.val) {preTail.next = tp1;tp1 = tp1.next;} else {preTail.next = tp2;tp2 = tp2.next;}sortedTail = sortedTail.next;while (tp1 != p2 && tp2 != nextHead) { // 歸并排序if (tp1.val < tp2.val) {sortedTail.next = tp1;tp1 = tp1.next;} else {sortedTail.next = tp2;tp2 = tp2.next;}sortedTail = sortedTail.next;}while (tp1 != p2) { // 處理剩余部分sortedTail.next = tp1;tp1 = tp1.next;sortedTail = sortedTail.next;}while (tp2 != nextHead) { // 處理剩余部分sortedTail.next = tp2;tp2 = tp2.next;sortedTail = sortedTail.next;}// - - - 排序后的處理 - - -sortedTail.next = nextHead; // 和下一段接上,如果到終點,則nextHead=null,避免了成環for (int i = 0; i < step * 2; i++) { // 更新preTailif (preTail != null) preTail = preTail.next;}p1 = nextHead;}step *= 2;}return newHead.next;} }

一把過

總結

以上是生活随笔為你收集整理的leetcode 148. Sort List | 148. 排序链表(最优解归并排序,O(1)空间)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。