【归并排序/快排/堆排序】912. 排序数组

力扣连接:. - 力扣(LeetCode)

归并排序

对左右子集合分别排序,然后合并两个有序数组

java 复制代码
class Solution {
    int[] nums;
    public int[] sortArray(int[] nums) {
        this.nums = nums;
        return sort(0, nums.length-1);
    }

    int[] sort(int st, int ed) {
        if(st == ed) {
            return new int[]{nums[st]};
        }
        //对左右分别排序
        int m = st + (ed-st)/2;
        int[] leftArr = sort(st, m);
        int[] rightArr = sort(m+1, ed);

        //合并两个有序数组
        int[] newArr = new int[ed-st+1];
        int i=0,j=0,k=0;
        while(i<leftArr.length && j<rightArr.length){
            if(leftArr[i]<rightArr[j]){
                newArr[k++]=leftArr[i++];
            }else{
                newArr[k++]=rightArr[j++];
            }
        }
        while(i<leftArr.length) newArr[k++] = leftArr[i++];
        while(j<rightArr.length) newArr[k++] = rightArr[j++];

        return newArr;
    }
}

快排

每次任意指定一个数作为标杆,小于标杆的放左边,大于标杆的放右边,对左右子数组重复这个流程

时间复杂度:O(n log n)

空间复杂度:O(n)

java 复制代码
class Solution {
    int[] nums;

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

    void sort(int st, int ed) {
        if (st >= ed)
            return;
        int p = st, l = st, r = ed;
        while (l < r) {
            // r指向第一个小于等于nums[p]的,注意这和下个while顺序不能随便换,要保证l和r最后指向小于等于nums[p]的地方
            while (l < r && nums[r] > nums[p])    r--;
            // l指向第一个大于nums[p]的
            while (l < r && nums[l] <= nums[p])    l++;
            swap(l, r);
        }
        swap(p, l);
        sort(st, l - 1);
        sort(l + 1, ed);
    }

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

}

堆排序

时间复杂度:O(nlogn)

视频讲解:排序算法:堆排序【图解+代码】_哔哩哔哩_bilibili

大顶堆:父节点比两个子节点都要大

下标规律:

节点 i 的父节点:(i-1)/2

节点 i 的左子节点:i*2+1

节点i的右子节点:(i+1)*2

维护大顶堆:从下往上,第一个有孩子节点的节点开始,取根节点、左孩子、右孩子之间的最大值 换到根节点处

排序:堆顶的元素一定是最大的,每次将堆顶元素放到尾部,然后剩下元素再次维护大顶堆,重复

java 复制代码
class Solution {
    int[] nums;
    public int[] sortArray(int[] nums) {
        this.nums = nums;
        int len = nums.length;
        sort(len);
        return nums;
    }

    void sort(int len) {
        //建堆
        for(int i= len/2-1;i>=0;i--) {
            heapify(len, i);
        }
        //排序
        for(int i=len-1;i>0;i--) {
            swap(i, 0);
            //i以后的数是已经排序好的
            heapify(i, 0);
        }

    }

    //i: 待维护的节点下标
    //len: 参与维护大顶堆的数组长度
    void heapify(int len, int i) {
        int biggest = i;
        int left = i*2+1;
        int right = (i+1)*2;
        //len用来约束递归终止条件
        if(left<len && nums[biggest]<nums[left]){
            biggest = left;
        } 
        if(right<len && nums[biggest]<nums[right]){
            biggest = right;
        }
        if(biggest != i){
            swap(biggest, i);
            heapify(len, biggest);
        }
    }

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

}
相关推荐
CoovallyAIHub3 小时前
中科大DSAI Lab团队多篇论文入选ICCV 2025,推动三维视觉与泛化感知技术突破
深度学习·算法·计算机视觉
NAGNIP3 小时前
Serverless 架构下的大模型框架落地实践
算法·架构
moonlifesudo4 小时前
半开区间和开区间的两个二分模版
算法
moonlifesudo4 小时前
300:最长递增子序列
算法
CoovallyAIHub9 小时前
港大&字节重磅发布DanceGRPO:突破视觉生成RLHF瓶颈,多项任务性能提升超180%!
深度学习·算法·计算机视觉
CoovallyAIHub9 小时前
英伟达ViPE重磅发布!解决3D感知难题,SLAM+深度学习完美融合(附带数据集下载地址)
深度学习·算法·计算机视觉
聚客AI1 天前
🙋‍♀️Transformer训练与推理全流程:从输入处理到输出生成
人工智能·算法·llm
大怪v1 天前
前端:人工智能?我也会啊!来个花活,😎😎😎“自动驾驶”整起!
前端·javascript·算法
惯导马工1 天前
【论文导读】ORB-SLAM3:An Accurate Open-Source Library for Visual, Visual-Inertial and
深度学习·算法
骑自行车的码农1 天前
【React用到的一些算法】游标和栈
算法·react.js