1. 程式人生 > 實用技巧 >【力扣】148. 排序連結串列

【力扣】148. 排序連結串列

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

進階:

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

示例 1:


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


輸入:head = [-1,5,3,4,0]
輸出:[-1,0,3,4,5]
示例 3:

輸入:head = []
輸出:[]

提示:

連結串列中節點的數目在範圍[0, 5 * 104]內
-105<= Node.val <= 105

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/sort-list
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

簡單做法:

public ListNode sortList(ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        List<ListNode> list = new ArrayList<ListNode>();
        while(head != null){
            list.add(head);
            head = head.next;
        }
        Collections.sort(list,(item1,item2) 
-> (item1.val - item2.val)); for(int i = 1; i < list.size(); i++){ list.get(i-1).next = list.get(i); } list.get(list.size() -1 ).next = null; return list.get(0); }

//首先先用昨天的題目的排序方式寫一遍、發現時間超限
    public ListNode sortList(ListNode head) {

        if(head == null || head.next == null){
            return head;
        }
        //我們使用 fast,slow 快慢雙指標法,奇數個節點找到中點,偶數個節點找到中心左邊的節點。
        ListNode fast = head.next;
        ListNode slow = head;
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
        }
        //將連結串列分割,分為左邊和右邊
        ListNode temp = slow.next;
        slow.next = null;//分割需要設定為null

        ListNode left = sortList(head);
        ListNode right = sortList(temp);

        //進行左邊和右邊連結串列的整和
        ListNode h = new ListNode();
        ListNode result = h;

        //這個迴圈沒有問題
        while(left != null && right != null){
            if(left.val < right.val){
                h.next = left;
                left = left.next;
            }else {
                h.next = right;
                right = right.next;
            }
            h = h.next;
        }
        //這裡有一些疑問: h.next = left  || h.next = right  為什麼要這麼設定,這兩種設定效果是一樣的
        //因為在迴圈結束時,有可能因為right為空了,或者left為空了,導致沒有給h.next 賦值,所以,再這裡複製。
        h.next = right != null ? right : left;

        return result.next;
    }

時間複雜度:O(logn)

空間複雜度:O(logn)

以上演算法的整體思想是:找到中心點,將連結串列分割,將分割後的連結串列排序,最後合併.