LeetCode 912. Sort an Array(快速排序/计数排序)

该博客主要讲解了LeetCode 912题目的解决方案,即如何对给定的整数数组进行升序排序。文章提供了两种方法:快速排序和计数排序。快速排序采用首元素为基准的策略,数组长度小于47时使用插入排序,平均时间复杂度为O(nlogn)。计数排序则通过创建一个bucket数组记录每个元素的出现次数,再顺序输出,时间复杂度为O(n),但空间复杂度为O(R),适用于元素取值范围与数组长度同数量级的情况。

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

题目来源:https://leetcode.com/problems/sort-an-array/

问题描述

912. Sort an Array

Medium

Given an array of integers nums, sort the array in ascending order.

 

Example 1:

Input: [5,2,3,1]

Output: [1,2,3,5]

Example 2:

Input: [5,1,1,2,0,0]

Output: [0,0,1,1,2,5]

 

Note:

  1. 1 <= A.length <= 10000
  2. -50000 <= A[i] <= 50000

------------------------------------------------------------

题意

数组排序

------------------------------------------------------------

思路

【思路一:快速排序】

快速排序,pivot取首元素,数组长度47以下用插入排序。快速排序平均时间复杂度O(nlogn)

【思路二:计数排序】

用一个bucket数组记录原数组每个元素出现多少次,然后顺序输出。时间复杂度O(n),空间复杂度O(R),其中R是原数组元素的取值范围。由于这题n和R同一数量级,因此计数排序是最快的方法

------------------------------------------------------------

代码

【思路一:快速排序】

class Solution {
    public static final int THRESHOLD = 47;
    
    // for debug
    private void printArray(int[] nums, int start, int end) {
        for (int i = start; i <= end; ++i) {
            System.out.print(nums[i] + ", ");
        }
        System.out.println();
    }
    
    private void insertionSort(int[] nums, int start, int end) {
        if (end - start < 1) {
            return;
        }
        for (int i = start + 1; i <= end; ++i) {
            int tmp = nums[i], j = i;
            while (--j >= start && nums[j] > tmp) {
                nums[j+1] = nums[j];
            }
            nums[j + 1] = tmp;
        }
    }
    
    /**
    * recursive quick sort
    */
    private void quickSort(int[] nums, int start, int end) {
        // too few elements, using insertion sort
        if (end - start < THRESHOLD) {
            insertionSort(nums, start, end);
            return;
        }
        int pivot = nums[start], left = start, right = end;
        while (left < right) {
            while (left < right && nums[right] > pivot) {--right;}
            nums[left] = nums[right];
            while (left < right && nums[left] <= pivot) {++left;}
            nums[right] = nums[left];
        }
        nums[left] = pivot;
        quickSort(nums, start, left-1);
        quickSort(nums, left+1, end);
    }
    
    public int[] sortArray(int[] nums) {
        int n = nums.length;
        if (n <= 1) {
            return nums;
        }
        quickSort(nums, 0, n-1);
        return nums;
    }
}

【思路二:计数排序】

class Solution {
    // for debug
    private void printArray(int[] nums, int start, int end) {
        for (int i = start; i <= end; ++i) {
            System.out.print(nums[i] + ", ");
        }
        System.out.println();
    }
    
    private void countSort(int[] nums) {
        int minNums = nums[0], maxNums = nums[0];
        for (int num: nums) {
            minNums = num < minNums? num: minNums;
            maxNums = num > maxNums? num: maxNums;
        }
        if (minNums == maxNums) {
            return;
        }
        int[] bucket = new int[maxNums - minNums + 1];
        for (int num: nums) {
            ++bucket[num - minNums];
        }
        int cnt = 0;
        for (int i=0, sizeBucket = bucket.length; i<sizeBucket; ++i) {
            for (int j=0; j<bucket[i]; ++j) {
                nums[cnt++] = i + minNums;
            }
        }
    }
    
    public int[] sortArray(int[] nums) {
        if (nums.length <= 1) {
            return nums;
        }
        countSort(nums);
        return nums;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值