(刷题笔记) Leetcode 912. 排序数组

本文探讨了LeetCode上的一道排序题目,作者通过实践多种排序算法如冒泡排序、计数排序、快速排序和归并排序来解决该问题。通过对每种算法的实现和比较,展示了不同算法的特点及效率,特别强调了在特定条件下计数排序的高效性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

给你一个整数数组 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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sort-an-array

解题思路

昨天遇到一道题,要用到归并排序,我看后面的题解没有看懂,然后去查了一下归并的思想,能理解但是不会写,所以去leetcode上搜了一下归并排序,然后就选了这一道题。

这道题一眼看过去就是直接调用库函数,sort一下就出结果了,哈哈哈,开个玩笑。

  1. 我一开始能想到的是冒泡排序(菜鸡的思考量,我只会这个),试了一下没通过。

  2. 然后试了计数排序,可以通过。这个思路比较简单,在知道数据的范围的情况下,将数据转换为坐标并统计该数出现的次数,然后按顺序将这些坐标值写到结果数组中,坐标统计多少次就写多少次。

  3. 接下来是快速排序,可以通过,具体思路有点复杂,我觉得这一篇写的比较清楚:快速排序 我的答案就是照着这篇改的。

  4. 最后是归并排序,可以通过,但是不知道为什么执行用时比较长,比计数和快排还有系统的sort都要慢。
    归并参考的是这一篇:[图解] 归并排序

代码(C++)

冒泡排序

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {

       // sort(nums.begin(),nums.end());

       for(int i=0;i<nums.size();++i){
           
           for(int j=0;j<nums.size()-i-1;++j){
               
               if(nums[j]>nums[j+1]){
                   int temp=nums[j];
                   nums[j]=nums[j+1];
                   nums[j+1]=temp;
               }

           }
       }
        
       return nums;

    }
};

计数排序

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        
     // 计数排序
     // 1 <= nums.length <= 50000
     // -50000 <= nums[i] <= 50000

        const int numsRange=50000*2+2;
        int arr[numsRange]={0};
        const int offset=50000; 
        vector<int> ans;

        for(int i=0;i<nums.size();++i){

            arr[nums[i]+offset]++;
        }

        for(int i=0;i<numsRange;++i){

             for(int j=0;j<arr[i];++j){
                 ans.push_back(i-offset);
             }

        }

        return ans;
    }
};

快速排序

class Solution {
public:

    int randomsort(vector<int>& nums,int left,int right){

        int lucky=rand()%(right-left+1)+left;
        int x=nums[lucky];

        while(left<right){

            while(left<right&&nums[right]>x){
                right--;
            }
            if(left<right){
                nums[lucky]=nums[right];
                if(left==lucky) left++;
            }

            while(left<right&&nums[left]<x){
                left++;
            }
            if(left<right){
                nums[right]=nums[left];
                lucky=left;
                right--;
            }
        }

        nums[left]=x;  
        return left;  
    }

    void quicksort(vector<int>& nums,int left,int right){

        if(left<0||left>right) return;
        if(left<right){
            int lucky=randomsort(nums,left,right);
            quicksort(nums,left,lucky-1);
            quicksort(nums,lucky+1,right);
        }

    }

    vector<int> sortArray(vector<int>& nums) {

        int left=0;
        int right=nums.size()-1;
        quicksort(nums,left,right);

        return nums;
        
    }
};

归并排序

class Solution {
public:

    void merge(vector<int>&nums,int left,int right,int mid){
        
        int p1=left;
        int p2=mid+1;
        int i=0;

        vector<int> temp(right-left+1);

        while(p1<=mid&&p2<=right){

            temp[i++]=nums[p1]<nums[p2]?nums[p1++]:nums[p2++];
            if(nums[p1]<nums[p2]){
                temp[i]=nums[p1];
                p1++;
            }
            else{
                temp[i]=nums[p2];
                p2++;
            }
            i++;
        }

        while(p1<=mid){
            temp[i]=nums[p1];
            ++i;++p1;
        }

        while(p2<=right){
            temp[i]=nums[p2];
            ++i;++p2;
        }

        for(int j=0;j<temp.size();++j){
            nums[left+j]=temp[j];
        }
    }

    void mergeSort(vector<int>& nums,int left,int right){

        if(left==right) return;
     
        int mid=left+(right-left)/2;
        mergeSort(nums,left,mid);
        mergeSort(nums,mid+1,right);
        merge(nums,left,right,mid);
        


    }

    vector<int> sortArray(vector<int>& nums) {
        int left=0;
        int right=nums.size()-1;
        mergeSort(nums,left,right);

        return nums;
    }
};
  • 写在最后:今天系统提醒多了一个关注,好开心,没想到我写的东西还有人看,我从10号开始写博客,这两个星期总共也就300多浏览量,有大半是我自己点出来的。
    不知道看我博客的都是些什么人,总之我写博客的目的就是记录一下刷题过程,希望找工作的时候会有一点用。
    找工作的时候发现简历上都没有可以写的东西,然后想了一下自己好像什么也不会,今年找工作看起来又特别难,只能加油了,希望顺利毕业,顺利找到工作,冲冲冲。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值