Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LeetCode] 912. Sort an Array #912

Open
grandyang opened this issue May 30, 2019 · 0 comments
Open

[LeetCode] 912. Sort an Array #912

grandyang opened this issue May 30, 2019 · 0 comments

Comments

@grandyang
Copy link
Owner

grandyang commented May 30, 2019

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. 1 <= A.length <= 10000
  2. -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 同步地址:

#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 题目讲解汇总(持续更新中...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant