[LeetCode] 912. Sort an Array 數組排序

2021-03-02 刷盡天下

Given an array of integers nums, sort the array in ascending order.

Example 1:

Input: [5,2,3,1]

Output: [1,2,3,5]

Example 2:

Input: [5,1,1,2,0,0]

Output: [0,0,1,1,2,5]

Note:

1<=A.length<=10000

-50000<=A[i]<=50000


這道題讓我們給數組排序,在平時刷其他題的時候,遇到要排序的時候,一般都會調用系統自帶的排序函數,像 C++ 中直接就調用 sort 函數即可,但是這道題考察的就是排序,再調用系統的排序函數就有些說不過去了。這裡需要自己實現排序功能,常見排序方法有很多,插入排序,選擇排序,堆排序,快速排序,冒泡排序,歸併排序,桶排序等等。它們的時間複雜度不盡相同,這道題貌似對於平方級複雜度的排序方法會超時,所以只能使用那些速度比較快的排序方法啦。題目給定了每個數字的範圍是 [-50000, 50000],並不是特別大,這裡可以使用記數排序 Count Sort,在 LeetCode 中也有直接利用這個解法的題Sort Colors,建立一個大小為 100001 的數組 count,然後統計 nums 中每個數字出現的個數,然後再從0遍歷到 100000,對於每個遍歷到的數字i,若個數不為0,則加入 count 數組中對應個數的 i-50000 到結果數組中,這裡的 50000 是 offset,因為數組下標不能為負數,在開始統計個數的時候,每個數字都加上了 50000,那麼最後組成有序數組的時候就要減去,參見代碼如下:


解法一:

class Solution {

public:

vector<int> sortArray(vector<int>& nums) {

int n = nums.size(), j = 0;

vector<int> res(n), count(100001);

for (int num : nums) ++count[num + 50000];

for (int i = 0; i < count.size(); ++i) {

while (count[i]-- > 0) {

res[j++] = i - 50000;

}

}

return res;

}

};


下面就是大名鼎鼎的快速排序了 Quick Sort,貌似 STL 中的內置 sort 函數就是基於快速排序的,只不過這裡要自己寫而已。在 LeetCode 中也有一道使用這個算法思想的題 Kth Largest Element in an Array。快排的精髓在於選一個 pivot,然後將所有小於 pivot 的數字都放在左邊,大於 pivot 的數字都放在右邊,等於的話放哪邊都行。但是此時左右兩邊的數組各自都不一定是有序的,需要再各自調用相同的遞歸,直到細分到只有1個數字的時候,再返回的時候就都是有序的了,參見代碼如下:


解法二:

class Solution {

public:

vector<int> sortArray(vector<int>& nums) {

quickSort(nums, 0, (int)nums.size() - 1);

return nums;

}

void quickSort(vector<int>& nums, int start, int end) {

if (start >= end) return;

int pivot = nums[start], i = start + 1, j = end;

while (i <= j) {

if (nums[i] > pivot && nums[j] < pivot) {

swap(nums[i++], nums[j--]);

}

if (nums[i] <= pivot) ++i;

if (nums[j] >= pivot) --j;

}

swap(nums[start], nums[j]);

quickSort(nums, start, j - 1);

quickSort(nums, j + 1, end);

}

};


我們也可以使用混合排序 Merge Sort,在 LeetCode 中也有一道使用這個思想的題 Count of Range Sum。混合排序的思想跟快速排序比較類似,但也不完全一樣,這裡其實是一種先對半分,一直不停的對半分,直到分到只有一個數字的時候返回,然後在返回的途中進行合併,合併的時候用到了一個臨時數組 tmp,先將區間 [start, end] 中的數字按順序存入這個臨時數組 tmp 中,然後再覆蓋原數組中的對應位置即可,參見代碼如下:


解法三:

class Solution {

public:

vector<int> sortArray(vector<int>& nums) {

mergeSort(nums, 0, (int)nums.size() - 1);

return nums;

}

void mergeSort(vector<int>& nums, int start, int end) {

if (start >= end) return;

int mid = (start + end) / 2;

mergeSort(nums, start, mid);

mergeSort(nums, mid + 1, end);

merge(nums, start, mid, end);

}

void merge(vector<int>& nums, int start, int mid, int end) {

vector<int> tmp(end - start + 1);

int i = start, j = mid + 1, k = 0;

while (i <= mid && j <= end) {

if (nums[i] < nums[j]) tmp[k++] = nums[i++];

else tmp[k++] = nums[j++];

}

while (i <= mid) tmp[k++] = nums[i++];

while (j <= end) tmp[k++] = nums[j++];

for (int idx = 0; idx < tmp.size(); ++idx) {

nums[idx + start] = tmp[idx];

}

}

};


Github 同步地址:

https://github.com/grandyang/leetcode/issues/912


類似題目:

Kth Largest Element in an Array

Sort Colors

Count of Range Sum


參考資料:

https://leetcode.com/problems/sort-an-array/

https://leetcode.com/problems/sort-an-array/discuss/319326/Java-merge-sort-implementation

https://leetcode.com/problems/sort-an-array/discuss/293820/Easiest-and-fastest-solution.-O(10n)

https://leetcode.com/problems/sort-an-array/discuss/280903/C%2B%2B-QuickSort-and-CountingSort-solutions


LeetCode All in One 題目講解匯總(持續更新中...)

相關焦點

  • LeetCode | 實現排序比較函數 | Relative Sort Array
    https://leetcode.com/problems/relative-sort-array/
  • Leetcode刷題-排序
    本文先介紹幾種常見的排序算法的python實現,接著對幾道涉及排序的leetcode題目進行實踐常見的排序算法冒泡排序進行n(數組長度n)次循環,每次從左向右兩個數依次比較,然後將未排序的最大值移到最右時間複雜度:O(n^2)  空間複雜度
  • Javascript數組系列四之數組的轉換與排序Sort方法
    Javascirpt 數組中的方法,數組的轉換是我們在項目的開發過程中,數據類型之間的轉換有著非常重要的作用,而數組轉換成其他數據類型是我們常見的一種。toString該方法是對數組轉換成字符串,數組的每一個元素都會調用 「toString」方法 ,返回一個新字符串。
  • LeetCode刷題第三周【數組(簡單)】
    (vector<int>& arr) {        vector<int> res = arr;//在定義一個數組        sort(arr.begin(), arr.end());//對原數組排序        int len = unique(arr.begin(), arr.end()) - arr.begin();//獲取去重後數組的長度
  • Javascript中 Array.sort 原理學習
    其實在代碼中一個sort()就可以解決,並且時間複雜度和空間複雜度相對都不會過高。其實sort()不光可以對數組進行排序, 基本數據類型的數組都可以, 並且可以實現對對象數組的排序。這個sort其實遠比我們想像的更加智能,它會基於要排序的數據量選擇性能更加優秀的排序算法來實現排序。
  • Excel – 多條件排序就用 sortby 函數
    O365 這次出了兩個排序函數,除了前段時間給大家講解過的 sort 以外,還有一個 sortby 函數。,用 sort 函數排序。, by_array1, [sort_order1], [by_array2, sort_order2],…) 參數:array:必需,要篩選的區域或數組。
  • JavaScript函數補完:sort()排序
    JavaScript實現多維數組、對象數組排序,其實用的就是原生的sort()方法,用於對數組的元素進行排序。
  • [LeetCode] 937. Reorder Data in Log Files 日誌文件的重新排序
    You have an array of logs.
  • [LeetCode] 918. Maximum Sum Circular Subarray 環形子數組的最大和
    假如沒有環形數組這一個條件,其實就跟之前那道 Maximum Subarray 一樣,解法比較直接易懂。這裡加上了環形數組的條件,難度就增加了一些,需要用到一些 trick。既然是子數組,則意味著必須是相連的數字,而由於環形數組的存在,說明可以首尾相連,這樣的話,最長子數組的範圍可以有兩種情況,一種是正常的,數組中的某一段子數組,另一種是分為兩段的,即首尾相連的,可以參見 大神 lee215 的帖子 中的示意圖。
  • LeetCode-75.顏色分類(Sort Colors)
    顏色分類給定一個包含紅色、白色和藍色,一共 n 個元素的數組,原地對它們進行排序,使得相同顏色的元素相鄰,並按照紅色、白色、藍色順序排列。此題中,我們使用整數 0、 1 和 2 分別表示紅色、白色和藍色。注意:不能使用代碼庫中的排序函數來解決這道題。
  • PHP數組排序函數大全
    介紹在眾多數組排序函數中,最常用的排序函數:sort、rsort、asort、arsort。主要區別1.有些函數基於 array 的鍵來排序,而其他的基於值來排序的:$array['key'] = 'value';。
  • PHP中數組元素升序、降序及重新排序的函數
    range()函數還具有第三個參數,該參數的作用是設定步長,比如range(1,9,3)創建的數組元素是:1、4、72、PHP中常規數組的排序一般數組中的各元素均以字符或數字表現的,所以可對數組元素進行升序排列,該功能函數為sort()。
  • PHP實現耐心排序(patience sort)算法
    耐心排序(patience sort)是一種排序算法,靈感來源於紙牌遊戲patience,並以此命名。該算法的一個變體可以有效地計算給定數組中最長遞增子序列的長度。該算法的名字來源於一個簡化版的patience紙牌遊戲。這個遊戲以一副洗牌開始。
  • JavaScript中原生Array數組方法詳解
    正在使用,.filter(fn(value,index,array),thisArgument)。value})7.sort(compareFunction)排序方法對數組成員進行排序,默認是按照字典順序排序。排序後,原數組將被改變。
  • ​LeetCode刷題實戰34:在排序數組中查找元素的第一個和最後一個位置
    今天和大家聊的問題叫做在排序數組中查找元素的第一個和最後一個位置,我們先來看題面:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-arrayGiven an array of integers nums sorted
  • Graph 新題型 Min Swaps to Sort Array
    後來經人提示才發現實際上這是一道披著 sort 外衣的 graph 題目。」最近我的小夥伴問了一道題非常有趣。題目不難,但是我之前從來沒有遇到過,所以好好研究了一下。現在分享給大家,有更好的解法的同學可以指點我,如果沒見過這題的我們可以一起探討。
  • 關於 JavaScript 的數組隨機排序
    /如果好文章投稿,點擊 → 了解詳情JavaScript 開發中有時會遇到要將一個數組隨機排序(shuffle)的需求,一個常見的寫法是這樣:function shuffle(arr) {   arr.sort(function () {      return Math.random() - 0.5;   });
  • ​LeetCode刷題實戰81:搜索旋轉排序數組 II
    今天和大家聊的問題叫做 搜索旋轉排序數組 II,我們先來看題面:https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/Suppose an array sorted in ascending order is rotated at some pivot
  • Excel – 告別繁瑣的菜單操作,用 sort 函數排序
    今天再給大家介紹 O365 的一個新函數 sort,毫不誇張地說,在 Excel 升級到新版本之前,sort 是我最為期待的新函數之一。:必需,要排序的區域或數組。[sort_index]:可選,表示要按第幾行或列排序。[sort_order]:可選,表示排序順序的數字;1 表示升序(默認值),-1 表示降序。
  • 每天一道leetcode18-四數之和
    正當班主任要繼續發話,只聽到角落默默想起來一個聲音:」K2」前言 2018.11.20號打卡今天的題目leetcode61:https://leetcode-cn.com/problems/rotate-list/description/昨天的題解題目 每天一道leetcode18- 四數之和分類:雙指針