近似有序數(shù)組排序

題目

已知一個(gè)幾乎有序的數(shù)組,幾乎有序是指,如果把數(shù)組排好順序的話,每個(gè)元素移動(dòng)的距離可以不超過k,并且k相對(duì)于數(shù)組來說比較小。請(qǐng)選擇一個(gè)合適的排序算法針對(duì)這個(gè)數(shù)據(jù)進(jìn)行排序。
給定一個(gè)int數(shù)組A,同時(shí)給定A的大小n和題意中的k,請(qǐng)返回排序后的數(shù)組。

測(cè)試用例 [2,1,4,3,6,5,8,7,10,9],10,2
返回 [1,2,3,4,5,6,7,8,9,10]

思路

比較直觀的一種想法是直接插入排序,每次插入的時(shí)間復(fù)雜度是O(k),所以總的時(shí)間復(fù)雜度是O(n*k)的,空間復(fù)雜度是O(1)。
還有一種解法是利用堆排序,維護(hù)一個(gè)大小為k的小根堆(類比滑動(dòng)窗口)。在遍歷數(shù)組的過程中,將根推出并賦值給原數(shù)組,在根部插入數(shù)組的下一個(gè)元素。然后從根部開始下沉,維護(hù)堆有序。當(dāng)窗口到達(dá)數(shù)組的末尾后,直接進(jìn)行普通的堆排序,依次推出最小根即可。插入元素并維護(hù)堆有序的時(shí)間復(fù)雜度是O(lgk),總的時(shí)間復(fù)雜度是O(n*lgk),空間復(fù)雜度是O(k)。

代碼如下,小根堆是通過下沉排序操作構(gòu)建的。

import java.util.*;

public class ScaleSort {
    public int[] sortElement(int[] A, int n, int k) {
        int[] aux = new int[k];
        for (int i = 0; i < k; i++) {
            aux[i] = A[i];
        }
        //建立一個(gè)小根堆,由aux[]數(shù)組組成
        for (int i = (k - 2) / 2; i >= 0; i--) {
            sink(aux, i, k - 1);
        }
        //每次取出小根堆的根,換為新的元素,再sink維護(hù)小根堆
        for (int i = 0; i < n - k; i++) {
            A[i] = aux[0];
            aux[0] = A[i + k];
            sink(aux, 0, k - 1);
        }
        //將根和尾節(jié)點(diǎn)交換,完成堆排序
        for (int i = n - k; i < n; i++) {
            A[i] = aux[0];
            swap(aux, 0, k-1);
            k--;
            sink(aux, 0, k-1);
        }
        return A;

    }

    //下沉排序操作
    private void sink(int[] A, int lo, int hi) {
        int child;
        while ((child = 2 * lo + 1) <= hi) {
            if (child < hi && A[child] > A[child + 1]) child++;
            if (A[lo] <= A[child]) break;
            swap(A, lo, child);
            lo = child;
        }

    }

    private void swap(int[] A, int i, int j) {
        int temp = A[i];
        A[i] = A[j];
        A[j] = temp;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 概述:排序有內(nèi)部排序和外部排序,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序,而外部排序是因排序的數(shù)據(jù)很大,一次不能容納全部...
    每天刷兩次牙閱讀 3,829評(píng)論 0 15
  • 1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 將一個(gè)記錄插入到已排序好...
    依依玖玥閱讀 1,357評(píng)論 0 2
  • 概述排序有內(nèi)部排序和外部排序,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序,而外部排序是因排序的數(shù)據(jù)很大,一次不能容納全部的...
    Luc_閱讀 2,379評(píng)論 0 35
  • 夜,慢慢的 爬上了湛藍(lán)的天空 它將藍(lán)色抹去 染上了點(diǎn)點(diǎn)墨色 夜,滿天的星空 在閃耀著, 月,慢慢的爬上了 頭頂,散...
    菱珂閱讀 192評(píng)論 1 1
  • 好在還有一個(gè)可以講案例的朋友,一路走過來,能這樣交流的朋友真的太少了。女生都陷在愛情,生活,老公,孩子,婆婆的世界...
    婷下來思考閱讀 270評(píng)論 0 0

友情鏈接更多精彩內(nèi)容