LeetCode.1122-相對排序數組(Relative Sort Array)

這是小川的第393次更新,第427篇原創

01 看題和準備

今天介紹的是LeetCode算法題中Easy級別的第258題(順位題號是1122)。給定兩個數組arr1arr2arr2中的元素是不同的,arr2中的所有元素也在arr1中。

arr1的元素進行排序,使arr1中元素的相對順序與arr2中的相對順序相同。未出現在arr2中的元素應按升序放置在arr1的末尾。

例如:

輸入:arr1 = [2,3,1,3,2,4,6,7,9,2,19],arr2 = [2,1,4,3,9,6]
輸出:[2,2,2,1,4,3,3,9,6,7,19]

注意

  • arr1.length,arr2.length <= 1000

  • 0 <= arr1 [i],arr2 [i] <= 1000

  • 每個arr2[i]都是不同的。

  • 每個arr2[i]都在arr1中。

02 第一種解法

題目的意思是對arr1分兩部分排序,前部分的順序要和arr2中元素的順序一樣,剩餘不是arr2中的元素,要按照增序排列。

直接翻譯題目即可,利用一個HashMap,將arr2中的元素值作爲key,因爲arr2中的元素不會重複出現,將value設統一值0,接着遍歷arr1,如果當前元素在HashMap中存在,就計數出現的次數,賦值到value上,反之就將其存入ArrayList中。遍歷arr2,將對應的元素寫入到結果數組中,出現幾次就寫入幾次。最後,如果ArrayList中有剩餘未處理的數據,就將其排序,再寫入到結果數組中去。

此解法的時間複雜度是O(N),最壞的情況可能到O(N^2),空間複雜度是O(N)

public int[] relativeSortArray(int[] arr1, int[] arr2) {
    int[] result = new int[arr1.length];
    List<Integer> left = new ArrayList<Integer>();
    Map<Integer, Integer> map = new HashMap<Integer, Integer>();
    for (int num : arr2) {
        map.put(num, 0);
    }
    for (int num : arr1) {
        if (map.containsKey(num)) {
            map.put(num, map.getOrDefault(num, 0)+1);
        } else {
            left.add(num);
        }
    }
    int index = 0, i = 0;
    while (i<result.length && index<arr2.length) {
        int count = map.get(arr2[index]);
        while (count > 0) {
            result[i++] = arr2[index];
            count--;
        }
        index++;
    }
    if (left.size() > 0) {
        Collections.sort(left);
        for (int j=0; j<left.size(); j++) {
            result[i++] = left.get(j);
        }
    }
    return result;
}


03 第二種解法

我們也可以使用計數排序算法,簡化計算步驟。

此解法的時間複雜度是O(N),空間複雜度是O(N)

public int[] relativeSortArray2(int[] arr1, int[] arr2) {
    int[] count = new int[1001];
    // 遍歷arr1中的元素並計數
    for (int num : arr1) {
        count[num]++;
    }
    int index = 0;
    // 處理arr2中的元素
    for (int num : arr2) {
        while (count[num] > 0) {
            arr1[index++] = num;
            count[num]--;
        }
    }
    // 處理剩餘不是arr2中的元素
    for (int i=0; i<count.length; i++) {
        while (count[i] > 0) {
            arr1[index++] = i;
            count[i]--;
        }
    }
    return arr1;
}


04 第三種解法

我們也可以直接重寫排序方法。

此解法的時間複雜度是O(N log(N)),最壞的情況可能到O(N^2 log(N)),空間複雜度是O(N)

public int[] relativeSortArray3(int[] arr1, int[] arr2) {
    Map<Integer, Integer> map = new HashMap<Integer, Integer>();
    for (int i=0; i<arr2.length; i++) {
        map.put(arr2[i], i);
    }
    // 爲方便後面排序,將arr1轉成Integer類型的數組
    Integer[] sort = new Integer[arr1.length];
    for (int i=0; i<sort.length; i++) {
        sort[i] = arr1[i];
    }
    Arrays.sort(sort, new Comparator<Integer>() {

        @Override
        public int compare(Integer a, Integer b) {
            // a和b都不是arr2中的元素
            if (!map.containsKey(a) && !map.containsKey(b)) {
                return a - b;
            }
            // 不能直接使用map.get(key),會報空指針
            return map.getOrDefault(a, arr1.length) - 
                    map.getOrDefault(b, arr1.length);
        }
    });
    // 將排序後的sort數組元素回寫到arr1中去
    for (int i=0; i<arr1.length; i++) {
        arr1[i] = sort[i];
    }
    return arr1;
}


05 小結

算法專題目前已連續日更超過八個月,算法題文章264+篇,公衆號對話框回覆【數據結構與算法】、【算法】、【數據結構】中的任一關鍵詞,獲取系列文章合集。

以上就是全部內容,如果大家有什麼好的解法思路、建議或者其他問題,可以下方留言交流,點贊、留言、轉發就是對我最大的回報和支持!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章