[数组排序] 0912. 排序数组

文章目录

      • [1. 题目链接](#1. 题目链接)
      • [2. 题目大意](#2. 题目大意)
      • [3. 示例](#3. 示例)
      • [4. 解题思路](#4. 解题思路)
      • [5. 参考代码](#5. 参考代码)

1. 题目链接

912. 排序数组 - 力扣(LeetCode)


2. 题目大意

描述:给定一个整数数组 nums。

要求:将该数组升序排列

说明

  • 1≤nums.length≤5∗104。
  • −5∗104≤nums[i]≤5∗104。

3. 示例

java 复制代码
输入:nums = [5,2,3,1]
输出:[1,2,3,5]
java 复制代码
输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]

4. 解题思路

假设数组的元素个数为 n 个,则快速排序的算法步骤如下:

  1. 哨兵划分:选取一个基准数,将数组中比基准数大的元素移动到基准数右侧,比他小的元素移动到基准数左侧。
    1. 从当前数组中找到一个基准数 pivot(这里以当前数组第 1 个元素作为基准数,即 pivot=nums[low])。
    2. 使用指针 i 指向数组开始位置,指针 j 指向数组末尾位置。
    3. 从右向左移动指针 j,找到第 1 个小于基准值的元素。
    4. 从左向右移动指针 i,找到第 1 个大于基准数的元素。
    5. 交换指针 i、指针 j 指向的两个元素位置。
    6. 重复第 3∼5 步,直到指针 ii和指针 j 相遇时停止,最后将基准数放到两个子数组交界的位置上。
  2. 递归分解:完成哨兵划分之后,对划分好的左右子数组分别进行递归排序。
    1. 按照基准数的位置将数组拆分为左右两个子数组。
    2. 对每个子数组重复「哨兵划分」和「递归分解」,直到各个子数组只有 1 个元素,排序结束。

5. 参考代码

java 复制代码
public class Solution {

    private Random random = new Random();

    // 三向快速排序:针对有大量重复元素的情况优化
    private void threeWayQuickSort(int[] nums, int low, int high) {

        if (low >= high) return;
        // 随机选取基准数并与第一个元素交换
        int pivotIndex = random.nextInt(high - low + 1) + low;
        swap(nums, low, pivotIndex);

        int pivot = nums[low];
        int lt = low;     // 维护小于基准数的区域
        int gt = high;    // 维护大于基准数的区域
        int i = low + 1;  // 遍历数组
        while (i <= gt) {

            if (nums[i] < pivot) {
                swap(nums, i++, lt++);
            } else if (nums[i] > pivot) {
                swap(nums, i, gt--);
            } else {

                i++;
            }
        }

        // 递归排序小于基准数的区域和大于基准数的区域
        threeWayQuickSort(nums, low, lt - 1);
        threeWayQuickSort(nums, gt + 1, high);
    }

    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }

    public int[] sortArray(int[] nums) {
        threeWayQuickSort(nums, 0, nums.length - 1);
        return nums;
    }
}

相关推荐
未来之窗软件服务9 分钟前
自己写算法(九)网页数字动画函数——东方仙盟化神期
前端·javascript·算法·仙盟创梦ide·东方仙盟·东方仙盟算法
豐儀麟阁贵16 分钟前
基本数据类型
java·算法
乐迪信息2 小时前
乐迪信息:基于AI算法的煤矿作业人员安全规范智能监测与预警系统
大数据·人工智能·算法·安全·视觉检测·推荐算法
hsjkdhs3 小时前
C++之多层继承、多源继承、菱形继承
开发语言·c++·算法
立志成为大牛的小牛3 小时前
数据结构——十七、线索二叉树找前驱与后继(王道408)
数据结构·笔记·学习·程序人生·考研·算法
星空下的曙光3 小时前
Node.js crypto模块所有 API 详解 + 常用 API + 使用场景
算法·node.js·哈希算法
StarPrayers.5 小时前
旅行商问题(TSP)(2)(heuristics.py)(TSP 的两种贪心启发式算法实现)
前端·人工智能·python·算法·pycharm·启发式算法
爱吃橘的橘猫5 小时前
嵌入式系统与嵌入式 C 语言(2)
c语言·算法·嵌入式
235165 小时前
【LeetCode】146. LRU 缓存
java·后端·算法·leetcode·链表·缓存·职场和发展
weixin_307779136 小时前
使用Python高效读取ZIP压缩文件中的UTF-8 JSON数据到Pandas和PySpark DataFrame
开发语言·python·算法·自动化·json