【算法基础】1.1 快速排序

news/2024/5/19 22:49:54 标签: 算法, leetcode, 排序算法, 快速排序

文章目录

  • 快速排序
    • 题目描述
    • 解法
    • 讲解
  • 第k个数(快速选择)
    • 题目描述
    • 解法
    • 讲解

本文主要讲解快速排序及其思路的相关应用。

快速排序

题目描述

给定你一个长度为 n 的整数数列。
请你使用快速排序对这个数列按照从小到大进行排序。
并将排好序的数列按顺序输出。

数据范围:1 ≤ n ≤ 100000
在这里插入图片描述
912. 排序数组 https://leetcode.cn/problems/sort-an-array/

解法

class Solution {
    public int[] sortArray(int[] nums) {
        int l = 0, r = nums.length - 1;
        quickSort(nums, l, r);
        return nums;
    }

    public void quickSort(int[] nums, int l, int r) {
        if (l >= r) return;

        int x = nums[l + r >> 1], i = l - 1, j = r + 1;
        while (i < j) {
            while (nums[++i] < x);
            while (nums[--j] > x);

            if (i < j) swap(nums, i, j);
        }

        quickSort(nums, l, j);
        quickSort(nums, j + 1, r);
    }

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

讲解

在这里插入图片描述
分治的思想。

  1. 确定分界点。可以取q[l], q[r], q[(l+r)/2], 随机
  2. 调整区间,让<=x的都在>=x的左边。
  3. 递归处理左右两段。

如何优雅地执行步骤二
双指针方法,i 和 j 分别在左右端点。当 nums[i] < x时,向右移;当nums[j] > x时,向左移;然后交换这两个元素的位置,直到 i 和 j 相遇。


e.g.
3 1 2 3 5
取x=2,得出
l 初始为0,r 初始为4;l = 0, r = 2时,进行交换,
2 1 3 3 5
此时 l = 0 < r = 2,继续移动,直到 r = 1时,进行交换,
1 2 3 3 5
此时 l = 0 < r = 1,继续移动,直到 l = r = 1,结束第一轮。

之后继续递归排序从下标0~1,以及2~4的部分。


另一个取 x = 3 的例子
在这里插入图片描述
可以看出,最后 i 和 j 是不一定相等的。
最后的结果是 :
i 之前的数都是 <= x 的,j 之后的数都是 >= x 的


关于

quickSort(nums, l, j);
quickSort(nums, j + 1, r);

能否可以将 j 和 j + 1 改成 i - 1 和 i 呢?
可以!
同时也要修改 x = nums[l + r + 1 >> 1]。(是不是觉得有点儿像二分?^ ^)

类似的,如果想取 x = nums[l],那么下面就是 j 和 j + 1;
如果想取 x= nums[r],那么下面就是 i - 1 和 i。

总之就是:
使用 j 做边界时,不要让x取到右边界。
使用 i 做边界时,不要让x取到左边界。


第k个数(快速选择)

题目描述

给定一个长度为 n 的整数数列,以及一个整数 k,请用快速选择算法求出数列从小到大排序后的第 k 个数。

数据范围
1 ≤ n ≤ 100000,
1 ≤ k ≤ n

在这里插入图片描述
215. 数组中的第K个最大元素 https://leetcode.cn/problems/kth-largest-element-in-an-array/

解法

class Solution {
    public int findKthLargest(int[] nums, int k) {
        int n = nums.length, l = 0, r = n - 1;
        return quickSelect(nums, l, r, k);
    }

    public int quickSelect(int[] nums, int l, int r, int k) {
        if (l == r) return nums[l];

        int i = l - 1, j = r + 1, x = nums[l + r >> 1];
        while (i < j) {
            while (nums[++i] > x);
            while (nums[--j] < x);
            if (i < j) swap(nums, i, j);
        }

        int ls = j - l + 1;
        if (k <= ls) return quickSelect(nums, l, j, k);
        else return quickSelect(nums, j + 1, r, k - ls);
    }

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

讲解

基于快速排序的思路,整体代码和快速排序类似。
计算出从 j 到 l 的距离是 j - l + 1,将其和 k 进行比较,如果 k 小,说明在前半部分,就直接搜索前半部分的第 k 个;如果 k 大,说明在后半部分,注意要搜索第 k - ls 个,因为后半部分的开始端点是 j + 1。(k - ls + j + 1 = k - j + l - 1 + j + 1 = k + l)。


快速排序的时间复杂度是:期望是O(nlongn)。
快速选择的时间复杂度是:直观地理解如果每次规模为 n 的问题我们都划分成 1 和 n - 1,每次递归的时候又向 n−1 的集合中递归,这种情况是最坏的,时间代价是 O(n ^ 2)。我们可以引入随机化来加速这个过程,它的时间代价的期望是 O(n)。


http://www.niftyadmin.cn/n/449.html

相关文章

算法 - 数字反转打印

目录 题目描述 输入描述 输出描述 用例 题目解析 算法源码 题目描述 小华是个对数字很敏感的小朋友&#xff0c;他觉得数字的不同排列方式有特殊美感。 某天&#xff0c;小华突发奇想&#xff0c;如果数字多行排列&#xff0c;第一行1个数&#xff0c;第二行2个&#x…

C语言学习之路(基础篇)笔记 01

说明&#xff1a;该篇博客是博主一字一码编写的&#xff0c;实属不易&#xff0c;请尊重原创&#xff0c;谢谢大家&#xff01; 第一个C语言程序 Visual Studio新建项目 源文件—添加—新建项 通过Visual Studio运行 通过gcc编译后运行 C语言编译过程 C语言编译步骤 1&a…

CMake中cmake_policy的使用

CMake中的命令cmake_policy用于管理CMake策略设置(Manage CMake Policy settings)。它通常被添加到project的CMakeLists.txt文件中&#xff0c;以改变CMake本身的行为&#xff0c;通常能够用新版本的CMake处理旧版本CMakeLists.txt features。 CMake从2.6版本开始&#x…

springboot:实现文件上传下载实时进度条功能【附带源码】

0. 引言 记得刚入行的时候&#xff0c;做了一个文件上传的功能&#xff0c;因为上传时间较久&#xff0c;为了用户友好性&#xff0c;想要添加一个实时进度条&#xff0c;显示进度。奈何当时技术有限&#xff0c;查了许久也没用找到解决方案&#xff0c;最后不了了之。 近来偶…

华为云数据灾备解决方案,你最佳的安全卫士

计算机的广泛传播和信息技术的不断发展&#xff0c;在方便了我们生活的同时&#xff0c;也让我们感受到了极大的威胁。对于个人而言&#xff0c;如果没有好的安全防护软件&#xff0c;在网上冲浪就有可能遭受到病毒和黑客的攻击&#xff0c;从而导致自身的隐私泄露&#xff0c;…

【附源码】计算机毕业设计SSM物流管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

CET-4 week 5th 前缀-下

com con cor col 共同一起 compose pose组成构成 connect 连接 collect lect选收集收藏 comfort fort强壮v安慰 n舒适 contribute v 贡献 导致I will contribute myself to learning English .contribute to lead to 导致 Efforts contribute to good scores. comm…

海航集团:曲折的发展历程

前言 备受瞩目的海航集团破产重整案不断有了新的进展&#xff0c; 2022年4月24日&#xff0c;根据海航集团官方宣布&#xff0c;海航集团等321家实质合并重整计划已经执行完毕并获得法院裁定确认。历时两年多的海航集团风险处置工作&#xff0c;终于落下帷幕。海航集团似乎正在…