1. 程式人生 > 其它 >【LeetCode刷題筆記(七十二)】之148 排序連結串列

【LeetCode刷題筆記(七十二)】之148 排序連結串列

技術標籤:# LeetCode連結串列資料結構演算法

本文章由公號【開發小鴿】釋出!歡迎關注!!!


老規矩–妹妹鎮樓:

一. 題目

(一) 題幹

給你連結串列的頭結點 head ,請將其按 升序 排列並返回 排序後的連結串列 。

進階:

你可以在 O(n log n) 時間複雜度和常數級空間複雜度下,對連結串列進行排序嗎?

(二) 示例

輸入:head = [4,2,1,3]
輸出:[1,2,3,4]

二. 題解

(一) 思路

之前我們使用插入排序對連結串列進行了排序,時間複雜度為O(n2),這裡我們使用歸併排序進行優化,將時間複雜度降低到O(nlogn)。歸併排序需要找到連結串列的中間節點,中間節點通過快慢指標來獲取,然後對兩邊的連結串列分別進行遞迴歸併排序,將兩個排好序的連結串列再整合起來,整合的過程就是簡單的判斷大小,將小的節點新增到新的連結串列中。


(二) 程式碼

Java:

/**
 * 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) { // 歸併排序 // 尾部是null return sortList(head, null); } public ListNode sortList(ListNode head, ListNode tail){ if(head == null){ return head; } if(head.next == tail){ head.next = null;
return head; } // 找到中間節點 ListNode low = head, fast = head; while(fast != tail){ fast = fast.next; low = low.next; if(fast != tail){ fast = fast.next; } } ListNode mid = low; ListNode s1 = sortList(head, mid); ListNode s2 = sortList(mid, tail); // 歸併兩個佇列 ListNode sorted = merge(s1, s2); return sorted; } // 正常的歸併演算法 public ListNode merge(ListNode head1, ListNode head2){ ListNode dumHead = new ListNode(0); ListNode temp = dumHead, temp1 = head1, temp2 = head2; while(temp1 != null && temp2 != null){ if(temp1.val <= temp2.val){ temp.next = temp1; temp1 = temp1.next; }else{ temp.next = temp2; temp2 = temp2.next; } temp = temp.next; } if(temp1 != null){ temp.next = temp1; }else if(temp2 != null){ temp.next = temp2; } return dumHead.next; } }