1. 程式人生 > >LeetCode Sort List(連結串列快速排序)

LeetCode Sort List(連結串列快速排序)

Sort a linked list in O(n log n) time using constant space complexity.

看到O(n log n)這個複雜度就想到了快速排序法。快速排序法主要思想為取一個基準點,採用交換+分治法完成快速排序。

對於單鏈表的快速排序,不能從後面開始遍歷,因為根據後繼找不到其前驅。因此採用以下步驟:

1.取每次的頭節點為基準節點,然後將這個節點從連結串列分離出來。用兩個指標,從頭節點的下一個節點遍歷。

2.找到一個小於頭節點的值,若是第一個小於頭節點的值,左連結串列的頭指向它,然後繼續遍歷,滿足小於就掛載在左連結串列的後面。相反,建立一個有連結串列。其實還是在原連結串列上建立。

3.使用遞迴分別對左連結串列和右連結串列進行如上操作,當頭節點為NULL時,遞迴返回。當左右連結串列都返回時,將原來的頭節點與左右連結串列掛上。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* sortList(ListNode* head) {
        if (head == NULL) {
            return head;
        }
        ListNode* tail = NULL;
        for (tail = head; tail -> next; tail = tail -> next);
        quicksort(head, tail);
        return head;
    }
    
    void quicksort(ListNode* &head, ListNode* &tail) {
        if (head == NULL) {
            return;
        }
        int key = head -> val;
        ListNode* p = head -> next;
        head -> next = NULL;
        ListNode* left_front = NULL, *right_front = NULL;
        ListNode* left_head = NULL, *left_tail = NULL;
        ListNode* right_head = NULL, *right_tail = NULL;
        
        while (p) {
            if (p -> val < key) {  // 與頭節點的值判斷
                if (!left_head) {  // 左連結串列
                    left_head = p;
                    left_front = p;
                }
                else {
                    left_front -> next = p;
                    left_front = p;
                }
                p = p -> next;
                left_front -> next = NULL;
            }
            else {
                if (!right_head) { // 右連結串列
                    right_head = p;
                    right_front = p;
                }
                else {
                    right_front -> next = p;
                    right_front = p;
                }
                p = p -> next;
                right_front -> next = NULL;
            }
        }
        left_tail = left_front;
        right_tail = right_front;
        
        quicksort(left_head, left_tail); // 左連結串列遞迴
        quicksort(right_head, right_tail);// 右連結串列遞迴
        // 左右連結串列遞迴返回,將原先頭節點掛在左右連結串列
        if (left_tail && right_head) { // 左右連結串列都為NULL
            left_tail -> next = head;
            head -> next = right_head;
            head = left_head;
            tail = right_tail;
        }
        else if (left_tail) {  // 右連結串列為NULL
            left_tail -> next = head;
            tail = head;
            head = left_head;
        }
        else if (right_head) {  // 左連結串列為NULL
            head -> next = right_head;
            tail = right_tail;
        }
    } 
};
但最後在LeetCode執行時,資料量很大時候就超時了。希望有人能提出解決辦法

相關推薦

LeetCode Sort List連結串列快速排序

Sort a linked list in O(n log n) time using constant space complexity. 看到O(n log n)這個複雜度就想到了快速排序法。快速排序法主要思想為取一個基準點,採用交換+分治法完成快速排序。 對於單鏈表

LeetCode | Reorder List連結串列重新排序

Given a singly linked list L: L0→L1→…→Ln-1→Ln, reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… You must do this in-place without altering the n

leetcode_效率題解_[python/C++]_147. Insertion Sort List連結串列插入排序

題目連結 【題目】 Sort a linked list using insertion sort. 【分析】 首先複習一下插入排序: void insert_sort( int a[] , int n ){ int i,j,t

147.leetcode Insertion Sort List(medium)[連結串列 插入排序]

Sort a linked list using insertion sort. 題目的意思是用插入排序的方式對一個連結串列進行排序。插入排序的思想是對每個元素檢測,將當前元素插入到之前有序序列的相應位置。這裡採用的是從前往後查詢的過程,首先找到第一個大於當前元素的節點,然

leetcode Rotate list 連結串列旋轉的python實現

題目如下: Given a list, rotate the list to the right by k places, where k is non-negative. For exampl

LeetCode:148. Sort List連結串列進行排序

Sort a linked list in O(n log n) time using constant space complexity. Example 1: Input: 4->2->1->3 Output: 1->2->3-

資料結構連結串列系列連結串列建立,連結串列刪除特定節點,連結串列氣泡排序連結串列快速排序

一、連結串列的理解: 1,各個節點間地址存放可以不連續,雖說是表,但是指標存在是為了找到其他的節點,如果連續了,都沒必要用連結串列了。 2,各節點依賴上一節點,要找到某一個節點必須找到他的上一個節點,所以要訪問連結串列,必須要知道頭指標,然後從頭指標訪問開始。 3,各節點間原來是獨立的,本

LeetCode:23. Merge k Sorted ListsK個連結串列進行排序

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. Example: Input: [   1->4->

[LeetCode-203] Remove Linked List Elements連結串列節點刪除

Remove all elements from a linked list of integers that have value val. Example Given: 1 –> 2 –&

連結串列快速排序

class Node: def __init__(self, x, next=None): self.value=x self.next=next def Qsort(head, tail): if head==None or tail==None o

[LeetCode] Linked List Components 連結串列元件

We are given head, the head node of a linked list containing unique integer values. We are also given the list G, a subset of the values in the link

19. Remove Nth Node From End of List連結串列

https://leetcode.com/problems/remove-nth-node-from-end-of-list/description/ 題目:刪除倒數第n個節點(遍歷只能一趟) 思路:雙指標 例如:1->2->3->4->5, n =

328. Odd Even Linked List連結串列

https://leetcode.com/problems/odd-even-linked-list/description/ 題目:將連結串列奇數位上的節點放到偶數位上的節點前面。 思路:分別構造兩條連結串列:奇數位的連結串列,偶數位的連結串列,最後一個奇數位節點的下一個節點為

Leetcode Linked List Problem 連結串列問題合集

1. Leet Code OJ 2. Add Two Numbers You are given two non-empty linked lists representing two non-negative integers. The digits are

[LeetCode 215]Kth Largest Element in an Array 分治法/快速排序

215. Kth Largest Element in an Array Find the kth largest element in an unsorted array. Note that it is the kth largest element in

1483:[HNOI2009]夢幻布丁連結串列+啟發式合併

1483:[HNOI2009]夢幻布丁 時間限制: 1000 ms 記憶體限制: 65536 KB 提交數: 2 通過數: 2 題目描述 N N N個布丁擺成一行,進行 M

c語言學生資訊管理系統連結串列、檔案

#include<stdio.h>                                               /*呼叫標頭檔案*/ #include<stdlib.h> #include<string.h> #inclu

資料結構連結串列的實現

1.連結串列的實現:插入結點,想要動態分配記憶體,如果分配的記憶體為空,則記憶體分配失敗。 2.序號查詢:for迴圈查詢,關鍵字查詢:while迴圈 3.連結串列的缺點就是不管查詢,刪除都是的從頭結點開始遍歷。 4.如果資料項只有一個,則只用一個結構體,如果資料項有

Java技術棧2排序演算法冒泡,快速排序

1.氣泡排序 氣泡排序是一種簡單的排序演算法。它重複地走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重複地進行直到沒有再需要交換,也就是說該數列已經排序完成。這個演算法的名字由來是因為越小的元素會經由交換慢慢“浮”到數列的頂端

學生成績管理系統連結串列的實現

/*所使用的標頭檔案*/ #include<stdio.h> #include<stdlib.h> #include<Windows.h> /*所呼叫的函式*/ struct LINK_NODE *creat(struct