算法-随机快排及荷兰国旗优化

文章目录

    • 算法介绍 :
    • 1. 随机快排解析
    • 2. 荷兰国旗问题
    • 3. 随机快排优化
    • 4. 总结随机快排

算法介绍 :

随机快速排序和传统的快速排序的逻辑本质是一致的,都是找到一个值作为划分的中间位置,左边数值均小于该数值,右边数值均大于该数值,但是与传统的快排又不一致的是,我们的这个位置是通过随机获得的,对于随机行为的时间复杂度不能简单的按照最坏的情况解读

1. 随机快排解析

下面是我们随机快排的代码实现

public class Sort {
    public static void quickSort(int[] nums) {
        if (nums == null || nums.length <= 1) {
            return;
        }

        quickSort(nums, 0, nums.length - 1);
    }

    //下面是经典版本随机快排的函数主体
    private static void quickSort(int[] nums, int left, int right) {
        if (left >= right) {
            return;
        }
        //在left -- right范围上随机出来一个数字
        int randn = nums[left + (int) (Math.random() * (right - left + 1))];
        int boundary = partiton(nums, left, right, randn);
        quickSort(nums, left, boundary - 1);
        quickSort(nums, boundary + 1, right);
    }

    //经典快排的partition过程
    private static int partiton(int[] nums, int left, int right, int randn) {
        //逐个遍历的下标
        int i = left;
        //用来区别 <= randn的边界位置(已经越界了)
        int j = left;
        //记录找到的x的位置(用于交换)
        int randIndex = left;
        while (i <= right) {
            if (nums[i] <= randn) {
                swap(nums, i, j);
                if (nums[j] == randn) {
                    randIndex = j;
                }
                i++;
                j++;
            } else {
                i++;
            }
        }
        swap(nums, j - 1, randIndex);
        return j - 1;
    }

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

下面主要解析一下上述代码的逻辑是什么
首先我们通过
(int)(Math.random()*(right - left + 1)) + left
这段代码可以随机产生一个left – right的下标值
然后我们就拿到该位置的随机数作为划分
之后通过partiton过程来进行快排的逻辑,其中定义了两个指针,一个遍历数组下标,一个进行边界位置的扩大,当遍历到随机数的时候我们就记录下来该随机数的下标,然后通过左右区间调用递归过程完成排序, 但是这个快排的逻辑在leetcode上是跑不过全部的,因为你一轮只能排出来一个数据

2. 荷兰国旗问题

在这里插入图片描述
荷兰国旗问题可以为我们的接下来的排序优化打下基础, 上面的排序说了我们创造了一个左边界线, 那为什么不创建一个有边界线呢 ? 荷兰国旗就是这样解决的,但是要注意的是,在移动右边界线的时候,遍历的下标值不可以移动,在移动左边界线却可以, 因为左边已经遍历过一轮了, 可以确定交换过来的元素属性,但是右边是不确定的, 代码实现如下

class Solution {
    public void sortColors(int[] nums) {
        int first = 0;
        int last = nums.length - 1;
        int i = 0;
        while(i <= last){
            if(nums[i] == 0){
                swap(nums,i++,first++);
            }else if(nums[i] == 1){
                i++;
            }else{
                swap(nums,i,last--);
            }
        }
    }
    public void swap(int[] nums,int i,int j){
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

3. 随机快排优化

有了上面的荷兰国旗的基础,我们的快排优化也是这样做的,逻辑也是定出来两个边界,然后逐个进行移动…
代码实现如下


    /**
     * 下面是根据荷兰国旗问题的改进版本(分为三个区间, 一次搞定一批)
     * 下面这个两个属性是左右边界的越界位置
     */
public class Sort{
    public int first = 0;
    public int last = 0;

    public void quickSortImprove(int[] nums) {
        if (nums == null || nums.length <= 1) {
            return;
        }
        quickSortImprove(nums, 0, nums.length - 1);
    }

    public void quickSortImprove(int[] nums,int left,int right){
        if (left >= right) {
            return;
        }

        int randn = nums[left + (int) (Math.random() * (right - left + 1))];
        partitonImprove(nums,left,right,randn);
        int fir = first;
        int la = last;
        quickSortImprove(nums,left,fir - 1);
        quickSortImprove(nums,la + 1, right);
    }
    private void partitonImprove(int[] nums,int left,int right,int randn){
        first = left;
        last = right;
        int i = left;
        while(i <= last){
            if(nums[i] < randn){
                swap(nums,i++,first++);
            }else if(nums[i] == randn){
                i++;
            }else{
                swap(nums,i,last--);
            }
        }
    }
    private static void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

在这里插入图片描述

4. 总结随机快排

随机快速排序算法

  • 随机快速排序的经典版本就是下面这样,随机出一个位置作为分界点,然后左右递归…
  • 我们下面的快排代码里面的 j 是作为左/右边界的越界位置存在 --> 随着下标指针的遍历(边界在不断地扩大)
  • Math.random方法的常数时间复杂度属于随机行为的时间复杂度
  • 荷兰国旗问题其实是随机快速排序的一种优化方式
  • 因为原本我们随即快排一次只能搞定一个数字, 优化之后我们一次可以搞定一批 x == randNum 的数据
  • 随机快速排序的时间复杂度与空间复杂度的估计
  • 关于随机行为的时间复杂度的估计不可以采用最坏的情况估计(因为最坏的情况就是无穷大),应该采用期望的方式估计
  • 最好情况(正好是中点位置) --> 时间复杂度 O(N*LogN)(Master公式) 空间复杂度O(LogN)(堆栈中树的高度)
  • 最坏情况(边界位置) --> 时间复杂度 O(N^2) 空间复杂度O(N)(堆栈中树的高度)
  • 经过大批数学家的证明(因为最终的时间复杂度应该算的是期望值(包含随机行为作为核心步骤))
  • –> 结论就是 时间复杂度 O(N*LogN) 空间复杂度O(LogN) --> 详见算法导论(有详细证明)
  • 所以 : 随机快排要比普通的快排更加优秀

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/672146.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Chrome DevTools

Console 面板 此章节请打开 justwe7.github.io/devtools/console/console.html 一起食用 一方面用来记录页面在执行过程中的信息&#xff08;一般通过各种 console 语句来实现&#xff09;&#xff0c;另一方面用来当做 shell 窗口来执行脚本以及与页面文档、DevTools 等进行交…

动态SQL IF语句

IF语句学习 第一种写法(标准) 我们先来看以下标准写法: select * from .. <where> <if test""> and ....... <if test""> and ....... <where> 我们用了一个where标签 , 内嵌if语句 第二种写法: 这是第二种写法:不用where标…

综合交易模型--雪球跟单参数说明支持qmt,同花顺

经过测试&#xff0c;目前完成了这个策略。支持多策略&#xff0c;支持全市场&#xff0c;包括股票&#xff0c;etf,可转债 全部的参数 { "雪球跟单":"跟单原理", "原理":"比重变大默认买入&#xff0c;变小默认卖出&#xff0c;持股…

【SpringBoot】SpringBoot项目关于默认port以及context path的配置 application.yml

application.yml server port [端口号] 配置/修改默认端口号 # server configurationserver:port: 8080context path [虚拟目录] 配置/修改默认虚拟目录 # server configurationserver:servlet:context-path: /spring configuration # spring configuration spring:applica…

mysql DDL——增删改

简略版&#xff1a; 详细版&#xff1a; DDL&#xff1a;对库中表的的记录进行增删改操作&#xff1b; 分别对应&#xff1a;添加&#xff08;insert&#xff09;&#xff0c;修改(update)&#xff0c;删除(delete); 一&#xff1a;添加数据 1. 对全部字段添加数据&#x…

【一刷《剑指Offer》】面试题 28:字符串的排列

牛客对应题目链接&#xff1a;字符串的排列_牛客题霸_牛客网 (nowcoder.com) 力扣对应题目链接&#xff1a;LCR 157. 套餐内商品的排列顺序 - 力扣&#xff08;LeetCode&#xff09; 核心考点 &#xff1a;全排列问题&#xff0c; DFS。 一、《剑指Offer》对应内容 二、分析题…

关于留痕的使用常见的问题

1. 登录微信 登录要导出数据的微信&#xff08;不支持微信多开&#xff0c;不支持部分老版本微信&#xff09; 相关信息 想把手机端的微信聊天记录转移到电脑上可以使用微信自带的聊天记录迁移功能 操作步骤&#xff1a; 安卓&#xff1a; 手机微信->我->设置->聊…

AI解密:语言模型生成下一个词的概率从何而来

在这个信息爆炸的时代&#xff0c;你是否曾好奇过&#xff0c;当你与聊天机器人流畅对话时&#xff0c;那些机智回复的背后&#xff0c;究竟隐藏着怎样的秘密&#xff1f;今天&#xff0c;就让我们一起乘坐时光机&#xff0c;深入语言模型的神秘腹地&#xff0c;揭开它预测下一…

【spring】第二篇 bean实例化

对象已经能交给Spring的IOC容器来创建了&#xff0c;但是容器是如何来创建对象的呢? 就需要研究下bean的实例化过程&#xff0c;在这块内容中主要解决两部分内容&#xff0c;分别是 bean是如何创建的 实例化bean的三种方式&#xff0c;构造方法,静态工厂和实例工厂 在讲解这…

iOS——类与对象底层探索

类和对象的本质 当我们使用OC创建一个testClass类并在main函数创建它的实例对象的时候&#xff0c;OC的底层到底是什么样的呢&#xff1f; 首先&#xff0c;我们要了解OC对象的底层结构&#xff0c;那么我们就得知道&#xff1a;OC本质底层实现转化其实都是C/C代码。 使用下面…

详解 Spark SQL 核心编程知识

一、SparkSQL 概述 1. 概念 Spark SQL 是 Spark 用于结构化数据 (structured data) 处理的 Spark 模块&#xff0c;使用 SQL 的方式简化 RDD 的开发 2. Hive VS SparkSQL Hive 是早期唯一运行在 Hadoop 上的 SQL-on-Hadoop 工具&#xff0c;但是 MapReduce 计算过程中大量的中…

java高并发实战<2>

##>>> 我们解决我们重复下单的问题 我们可以使用mysql 的唯一索引 &#xff0c;在我们的数据库层面保证不能重复下单 我可以控制是唯一的 同一个用户 针对于同一个商品只可以买一个 重复下单 优化 我们 >1.使用数据库唯一索引 一旦是 2个请求 因为mysql 有行级…

万物皆有定数

前段时间&#xff0c;测算一个女孩的婚姻&#xff0c;她年底或明年必有婚姻&#xff0c;因为蛇冲猪日&#xff0c;冲动夫宫&#xff0c;就有婚姻出现。不过&#xff0c;按照她总体八字分析&#xff0c;是要晚婚的&#xff0c;但这个运已到&#xff0c;所以&#xff0c;就要允许…

【文献阅读】汽车上的信息安全工程

文章目录 前言 基本概念 信息安全评估 信息安全措施 测试验证 参考文献 前言 见《汽车电子——产品标准规范汇总和梳理&#xff08;信息安全&#xff09;》 基本概念 道路车辆信息安全 cybersecurity 使资产受到充分保护&#xff0c;免受道路车辆相关项、其功能及其电气或…

运放的自激振荡问题

运放的自激振荡指的是当运算放大器加电后&#xff0c;在没有外部信号输入的情况下&#xff0c;输出端会出现高频类似于正弦波的波形。 运算放大器产生自激的原因以及解决办法-CSDN博客 a)当振荡由分布电容、电感等引起时&#xff0c;可通过反馈端并联电容&#xff0c;抵消影响…

Java web应用性能分析之【java进程问题分析工具】

Java web应用性能分析之【java进程问题分析概叙】-CSDN博客 前面大概讲了java进程问题分析流程&#xff0c;这里再小结一下分析工具&#xff0c;后面也会小结一下java进程问题分析定位。 1.分析工具 1.1.linux命令工具 参考&#xff1a;Java web应用性能分析之【Linux服务器性…

汪小菲直播翻车亲儿子直言麻六记有异味网友热议引爆话题

汪小菲直播翻车&#xff01;亲儿子直言“麻六记”有“异味”&#xff0c;网友热议引爆话题在星光璀璨的娱乐圈&#xff0c;汪小菲一直以家庭幸福、事业有成的形象示人。然而&#xff0c;近日的一场直播让他遭遇了前所未有的尴尬。在直播中&#xff0c;汪小菲兴致勃勃地向观众跨…

创新实训2024.05.29日志:评测数据集与baseline测试

1. 评测工作 在大模型微调和RAG工作都在进行的同时&#xff0c;我们搭建了一套评测数据集。这套数据集有山东大学周易研究中心背书。主要考察大模型对于易学基本概念与常识的理解与掌握能力。 1.1. 构建评测集 在周易研究中心的指导下&#xff0c;我们构建出了一套用以考察大…

Linux系统下+jmeter分布式压测

一.配置jdk&#xff08;Linux机都需配置同一个版本&#xff09; 下载Linux系统的jdk&#xff0c;下载地址&#xff1a;https://repo.huaweicloud.com/java/jdk/ 下载后的jdk文件上传到 /opt目录下 进入opt目录&#xff0c;查看jdk文件 cd /opt ll 1.解压文件 tar xzvf jd…

为什么改变进制传输系统码长不变

目录 直接上图片 问题分析 传信率与传码率 多进制调制 码长不变的理解 误码率考量 总结 直接上图片 问题分析 在讨论这个问题时&#xff0c;通常是指在保持RB&#xff08;码元传输速率&#xff0c;传码率&#xff0c;符号率&#xff0c;波特率&#xff09;不变的情况下&a…