「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战」
题目:
912. 排序数组
给你一个整数数组 nums
,请你将该数组升序排列。
示例 1:
输入: nums = [5,2,3,1]
输出: [1,2,3,5]
示例 2:
输入: nums = [5,1,1,2,0,0]
输出: [0,0,1,1,2,5]
提示:
1 <= nums.length <= 50000
-50000 <= nums[i] <= 50000
思路:
这道题目自由度就非常高了,快速排序,希尔排序啥的随便挑一个用就行,由于我之前已经给大家介绍过了其他的算法,这次给大家介绍个没说过的吧 -- 归并排序。
归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
作为一种典型的分而治之思想的算法应用,归并排序的实现由两种方法:
- 自上而下的递归(所有递归的方法都可以用迭代重写,所以就有了第 2 种方法);
- 自下而上的迭代;
算法步骤
- 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
- 设定两个指针,最初位置分别为两个已经排序序列的起始位置;
- 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
- 重复步骤 3 直到某一指针达到序列尾;
- 将另一序列剩下的所有元素直接复制到合并序列尾。
实现:
/**
* @param {number[]} nums
* @return {number[]}
*/
function sortArray(arr) {
const n = arr.length;
// 不需要排序了
if (n < 2) {
return arr;
}
const mid = Math.ceil(n / 2),
left = arr.slice(0, mid),
right = arr.slice(mid);
// 递归, 分别对左右数组进行排序后合并
return merge(sortArray(left), sortArray(right));
}
function merge(left = [], right = []) {
let result = [];
// 数值小的先放进数组,这样子就实现从小到大排列
while (left.length && right.length) {
if (left[0] <= right[0]) {
result.push(left.shift());
} else {
result.push(right.shift());
}
}
// es6新语法,骚操作
result.push(...left, ...right);
return result;
}
看懂了的小伙伴可以点个关注、咱们下道题目见。如无意外以后文章都会以这种形式,有好的建议欢迎评论区留言。