[前端]_一起刷leetcode 912. 排序数组

389 阅读2分钟

「这是我参与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. 1 <= nums.length <= 50000
  2. -50000 <= nums[i] <= 50000

思路:

这道题目自由度就非常高了,快速排序,希尔排序啥的随便挑一个用就行,由于我之前已经给大家介绍过了其他的算法,这次给大家介绍个没说过的吧 -- 归并排序。

归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

作为一种典型的分而治之思想的算法应用,归并排序的实现由两种方法:

  • 自上而下的递归(所有递归的方法都可以用迭代重写,所以就有了第 2 种方法);
  • 自下而上的迭代;

算法步骤

  1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
  2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置;
  3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
  4. 重复步骤 3 直到某一指针达到序列尾;
  5. 将另一序列剩下的所有元素直接复制到合并序列尾。

mergeSort.gif

实现:

/**
 * @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;
}

看懂了的小伙伴可以点个关注、咱们下道题目见。如无意外以后文章都会以这种形式,有好的建议欢迎评论区留言。