当前位置: 首页 > news >正文

【LeetCode】912. 排序数组、手撕快速排序

题目

【LeetCode】912. 排序数组

给你一个整数数组 nums,请你将该数组升序排列。

你必须在 不使用任何内置函数 的情况下解决问题,时间复杂度为 O(nlog(n)),并且空间复杂度尽可能小。

    示例 1:

    输入:nums = [5,2,3,1]
    输出:[1,2,3,5]
    解释:数组排序后,某些数字的位置没有改变(例如,2 和 3),而其他数字的位置发生了改变(例如,1 和 5)。
    

    示例 2:

    输入:nums = [5,1,1,2,0,0]
    输出:[0,0,1,1,2,5]
    解释:请注意,nums 的值不一定唯一。
    

    提示:

    • 1 <= nums.length <= 5 * 104
    • -5 * 104 <= nums[i] <= 5 * 104

    解题思路

    核心要点:

    • 将整数数组按升序排列
    • 数组长度可能达到 5×10^4,需要高效的排序算法
    • 可以使用多种排序算法,选择时间复杂度较低的算法更合适

    对于这个问题,快速排序是一个很好的选择,它的平均时间复杂度为 O(n log n),在实际应用中表现优异。快速排序的基本思想是:

    1. 选择一个基准元素(通常是数组的第一个或最后一个元素)
    2. 将数组分区:所有比基准小的元素移到基准前面,所有比基准大的元素移到基准后面
    3. 递归地对基准前后的子数组进行排序

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    代码实现

    import java.util.Arrays;public class SortArray {public int[] sortArray(int[] nums) {quickSort(nums, 0, nums.length-1);return nums;}void quickSort(int[]nums,int l,int r){if(l >= r)return;//选取基准值x,此处为数组中间元素的值 //>>>是无符号右移,等价(l + r) / 2int i = l - 1,j = r + 1,x = nums[(l + r)>>>1];while(i < j){// 从左向右找到第一个大于x的元素do i++;while(nums[i] < x);// 从右向左找到第一个小于x的元素do j--;while(nums[j] > x);// 如果i和j没有交错,则交换nums[i]和nums[j]的值if(i < j)swap(i,j,nums);}/*while(i < j)循环结束时,i和j可能满足以下三种情况之一:i == j(刚好相遇)i > j(交叉)i指向第一个≥pivot的元素,j指向最后一个≤pivot的元素关键特性:无论哪种情况,j左侧的所有元素都≤pivot,j右侧的所有元素都≥pivot。因此j是安全的分区点。*/// 对基准值左侧的子数组进行快速排序quickSort(nums, l, j);// 对基准值右侧的子数组进行快速排序quickSort(nums, j+1, r);}void swap(int i,int j,int [] nums){int temp = nums[i];nums[i] = nums[j];nums[j] = temp;}// 测试示例public static void main(String[] args) {SortArray solution = new SortArray();int[] nums1 = {5,2,3,1};System.out.println(Arrays.toString(solution.sortArray(nums1)));  // 输出:[1,2,3,5]int[] nums2 = {5,1,1,2,0,0};System.out.println(Arrays.toString(solution.sortArray(nums2)));  // 输出:[0,0,1,1,2,5]int[] nums3 = {3,1,2};System.out.println(Arrays.toString(solution.sortArray(nums3)));  // 输出:[1,2,3]}
    }

    复杂度分析

    • 时间复杂度:O(n log n),其中 n 是数组的长度。快速排序的平均时间复杂度为 O(n log n),最坏情况下为 O(n²),但通过合理选择基准元素(如随机选择)可以避免最坏情况。
    • 空间复杂度:O(log n),主要是递归调用栈的空间开销,最坏情况下为 O(n)。

    其他可行解法

    除了快速排序,还有其他高效的排序算法可以解决这个问题:

    1. 归并排序:时间复杂度 O(n log n),空间复杂度 O(n),是一种稳定的排序算法
    2. 堆排序:时间复杂度 O(n log n),空间复杂度 O(1),但实际性能略逊于快速排序
    3. Java 内置排序:可以直接使用 Arrays.sort(nums),底层通常采用双轴快速排序(Dual-Pivot QuickSort)

    对于本题,快速排序是综合性能较好的选择,既保证了高效性,又易于理解和实现。

    关键要点

    • 快速排序的核心是分区操作,通过选择基准元素将数组分为两部分
    • 递归思想的应用,将大问题分解为小问题解决
    • 交换操作的实现,用于调整元素位置
    • 边界条件的处理,当子数组长度为 1 时停止递归
    http://www.dtcms.com/a/403231.html

    相关文章:

  1. 国内企业建站模板淘宝代运营去哪里找
  2. VTK基础(05):VTK的渲染窗口嵌入到QT的控件当中
  3. 深入解析 List 容器组件:构建高效、可交互的列表解决方案
  4. 06.容器存储
  5. 自己做的网站为何手机不能浏览快闪ppt模板免费下载
  6. 动态内存管理 干货2
  7. pdf转图片:pdf2image
  8. 高校档案网站建设网站如何做成app
  9. 画质及画面刷新率如何调整?正式升级!2K240帧原画级教程
  10. 兰州网站的建设群晖搭建的wordpress外网访问
  11. Redis常见八股文
  12. Rust HashMap详解
  13. 定制网站开发哪家强千旺crm客户管理系统
  14. 2026年考研10月10日开始网上预报名
  15. antd表格操作实现勾选
  16. 性能测试-jmeter14-性能项目分析
  17. 网站建设制作小程序开发卖友情链接的哪来那么多网站
  18. react的依赖项数组
  19. 购物网站下载长沙做网站比较好的公司
  20. 大模型剪枝系列——基于梯度的剪枝
  21. 【论文阅读】A Survey of Reinforcement Learning for Large Reasoning Models
  22. 《Cursor+Copilot引领的AI辅助开发路径》
  23. 调用 vLLM API 时常用的三种请求头模板:普通请求、带鉴权请求、流式请求。
  24. 第6.3节 iOS Agent开发<一>
  25. 多多返利网站建设程序中装建设股票
  26. 处理限流、缓存与数据一致性:1688 API 实时数据采集的技术细节
  27. 网站建设需要什么编程语言wordpress 飞龙博客 许愿墙
  28. Pythoner 的Flask项目实践-绘制点/线/面并分类型保存为shpfile功能(Mapboxgl底图)
  29. 汽车渗透测试自动化工具和过程
  30. 南京大学 LLM开发基础(二)大语言模型解析 -- 基于HF LlaMA实现的讲解