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

文章目录

    • 算法介绍 :
    • 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) --> 详见算法导论(有详细证明)
  • 所以 : 随机快排要比普通的快排更加优秀

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

国内的期权模拟账户怎么申请?

国内的期权模拟账户可以在券商和期权分仓平台处申请开通&#xff0c;期权相比于股票具有杠杆投资、风险控制等新特性。 期权模拟交易客户端能够提供期权的开平仓交易、备兑开仓&#xff0f;平仓、行权等交易指令&#xff0c;下文为大家介绍国内的期权模拟账户怎么申请&#xff…

2024 cicsn Ezheap

文章目录 检查 libc2.35利用adddeleeditshow 思路exp结果 检查 libc2.35 利用 add 0x80个chunk&#xff0c;遍历选一个没有被用的&#xff0c;输入的size<0x501,然后malloc后会清零安装输入的size&#xff0c;然后输入内容&#xff0c;长度也是输入的size dele 指定索引…

第十六课,海龟画图:设置画笔颜色、宽度函数,移动画笔函数

一&#xff0c;turtle.color()&#xff1a;画笔颜色函数 这个函数能设置画笔画出来的颜色&#xff0c;当然&#xff0c;使用它之前你需要认识有哪些“颜料”可供你选择&#xff0c;turtle库的color()函数可以选择以下颜色&#xff1a; "white" 白色&#xff08;建议…

3步轻松月入过万,APP广告新模式大揭秘!

万万没想到&#xff1a;用这个APP广告模式&#xff0c;月入过万竟然如此简单&#xff01; 在移动应用开发的世界里&#xff0c;变现一直是一道难题。 许多APP开发者和产品经理为了提高收益、增强用户黏性&#xff0c;不断尝试各种策略。 然而&#xff0c;很多时候&#xff0c…

2024-6-1 石群电路-20

2024-6-1&#xff0c;星期六&#xff0c;18:24&#xff0c;天气&#xff1a;晴&#xff0c;心情&#xff1a;晴。已经到学校啦&#xff0c;本来打算今天休息一天不更了&#xff0c;但是觉得可以更新完再休息&#xff0c;没有这么累&#xff0c;哈哈哈哈&#xff0c;这就不得不说…

阿里云部署nodejs

目录 1、安装node.js 1-1 进入opt/software 1-2 下载node.js安装包 1-3 解压 2 配置环境变量 2-1 vim中配置环境变量 2-2 命令行中保存环境变量 2-3 检查安装版本 2-3 更换镜像 3、上传node.js项目 1-1 启动项目 1-2 配置对应的安全组 ​编辑 4、pm2启动多个node项…

Linux目录的基本结构(RHEL8系统基本使用之文件操作)

1.Linux的目录树结构 2.各目录的功能介绍 3.理解文件路径表示方法 Who&#xff1f;——>当前登录的用户 Where?——>路径 我要在哪儿创建文件&#xff1f; 我要删除什么地方的什么文件&#xff1f; 我所要查看的文件在哪里&#xff1f; What?——>操作命令 Ho…

Ultralytics x SwanLab:可视化YOLO模型训练

Ultralytics是YOLO官方团队推出的CV训练与推理框架&#xff0c;不仅支持目标检测任务&#xff0c;还支持分割、姿态识别、分类等更多任务。 SwanLab是一个深度学习实验管理与训练可视化工具&#xff0c;由西安电子科技大学团队打造&#xff0c;融合了Weights & Biases与Ten…

java web爬虫

目录 读取本地文件 从网站读取文件 java爬虫 总结 读取本地文件 import java.io.File; import java.io.PrintWriter; import java.util.Scanner;public class ReplaceText {public static void main() throws Exception{File file new File("basic\\test.txt"…

vue3:插槽、具名插槽、条件插槽、作用域插槽、具名作用域插槽 一次性搞清楚 --- 通俗易懂

1、插槽的使用&#xff1a; ~父组件index.vue&#xff1a; <h3>我是父组件testSlot</h3> <!-- 调用子组件alertBox测试插槽 --> <alertBox></alertBox> <alertBox>Something good will be happened. /alertBox> <br> ~alertBo…

钓虾馆计时计费怎么用,佳易王钓虾馆钓鱼场计时器工具软件操作教程

钓虾馆计时计费怎么用&#xff0c;佳易王钓虾馆钓鱼场计时器工具软件操作教程 一、前言 以下软件操作教程以&#xff0c;佳易王钓虾馆钓鱼场计时计费软件为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 可以多种单价计费方式&#xff0c;在系统…

Elasticsearch 认证模拟题 - 4

一、题目 生成快照&#xff0c;或快照生命周期 1.1 考点 快照生命周期&#xff08;最好通过界面化配置&#xff09;创建仓库创建快照 &#xff08;因为这个需要部署共享文件&#xff0c;所以这个我就在虚拟机上简单操作一下&#xff09; 注&#xff1a; 部署共享文件系统可…

【开发利器】使用OpenCV算子工作流高效开发

学习《人工智能应用软件开发》&#xff0c;学会所有OpenCV技能就这么简单&#xff01; 做真正的OpenCV开发者&#xff0c;从入门到入职&#xff0c;一步到位&#xff01; OpenCV实验大师Python SDK 基于OpenCV实验大师v1.02版本提供的Python SDK 实现工作流导出与第三方应用集…

MySql全文索引+Ngram

一、关于Ngram 1.1 什么是ngram MySQL 内置的全文解析器使用单词之间的空格作为分隔符&#xff0c;这对于不使用空格做分隔符的语言是一种限制。为了解决这一限制&#xff0c;MySQL提供了一个支持中文、日文和韩文&#xff08;CJK&#xff09;的ngram全文解析器。ngram 全文解…

图像加雾算法的研究与应用

目录 前言 一、图像加雾 1、基于传统方法的雾图合成 2、基于深度学习的雾图合成 3、基于Lightroom Classic实现软件加雾 4、基于深度图的方法实现加雾 二、开源的数据集 三、参考文章 前言 在去雾任务当中&#xff0c;训练和评估去雾算法需要大量的带有雾霾和无雾霾的…

聊聊几种常见的分布式Session解决方案

highlight: xcode theme: vuepress 问题引入&#xff1a;什么是分布式Session&#xff1f; 分布式 Session 是指在多台服务器之间共享和管理用户的会话数据&#xff0c;使得用户的会话状态能够在不同的服务器上保持一致。这样&#xff0c;无论用户的请求被路由到哪台服务器&…

【Go语言精进之路】构建高效Go程序:掌握变量、常量声明法则与iota在枚举中的奥秘

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 引言一、变量1.1 基础知识1.2 包级变量的声明形式深入解析&#x1f4cc; 声明并同时显式初始化&#x1f4cc; 声明但延迟初始化&#x1f4cc; 声明聚类与就近原则 1.3 局部变量的声明形式深入探讨&#x1f4cc; 延迟初始化的…

你认识nginx吗,nginx是做什么的,nginx可以做什么 --1)nginx介绍

一.Nginx 介绍 Nginx&#xff08;发音同engine x&#xff09;是一个异步框架的 Web 服务器&#xff0c;也可以用作反向代理&#xff0c;负载平衡器 和 HTTP 缓存。该软件由 Igor Sysoev 创建&#xff0c;并于2004年首次公开发布。同名公司成立于2011年&#xff0c;以提供支持。…

PHP:集成Xunsearch生成前端搜索骨架

如果是安装宝塔&#xff0c;我们在集成xunsearch的时候就会比较简单&#xff0c;后面我们在介绍其他的接入方式&#xff1b; 首先我们进入到宝塔管理后台&#xff1a;【软件商店】-【输入xun】-【点击xunsearch】直接安装即可 安装成功之后&#xff0c;会自动在www/server中创…

大模型高级 RAG 检索策略:自动合并检索

节前&#xff0c;我们星球组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、参加社招和校招面试的同学. 针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 汇总合集&…