荷兰国旗问题以及快速排序

文章目录

  • 一、荷兰国旗问题
    • 1、啥是荷兰国旗问题
    • 2、荷兰国旗问题的抽象
    • 3、解决的思路
    • 4、详细的参考代码
  • 二、快速排序
    • 1、啥是快排(排序流程)
    • 2、抽象后的快排流程
    • 3、详细的参考代码

大家好,我是周一。

最近几篇算法,我们都是聊的归并排序,归并排序也说的差不多了,今天讲讲快速排序。

一、荷兰国旗问题

1、啥是荷兰国旗问题

荷兰国旗是由红白蓝3种颜色的条纹拼接而成,如下图所示:

图片
假设这样的条纹有多条,且各种颜色的数量不一,并且随机组成了一个新的图形,新的图形可能如下图所示,但不仅仅只有这一种情况:
图片

需求是:把这些条纹按照颜色排好,红色的在上半部分,白色的在中间部分,蓝色的在下半部分,我们把这类问题称作荷兰国旗问题。

2、荷兰国旗问题的抽象

我们把荷兰国旗问题抽象成数组的形式是下面这样的:

给定一个整数数组和一个值M(存在于原数组中),要求把数组中小于M的元素放到数组的左边,等于M的元素放到数组的中间,大于M的元素放到数组的右边,最终返回一个整数数组,只有两个值,0位置是等于M的数组部分的左下标值、1位置是等于M的数组部分的右下标值。

进一步抽象为更加通用的形式是下面这样的:

给定数组arr,将[l, r]范围内的数(当然默认是 [ 0 - arr.length - 1 ]),小于arr[r](这里直接取数组最右边的值进行比较)放到数组左边,等于arr[r]放到数组中间,大于arr[r]放到数组右边。最后返回等于arr[r]的左, 右下标值。

3、解决的思路

定义一个小于区,一个大于区;遍历数组,挨个和arr[r]比较,

(1)小于arr[r],与小于区的后一个位置交换,当前位置后移;

(2)等于arr[r],当前位置直接后移;

(3)大于arr[r],与大于区的前一个位置交换,当前位置不动(交换到此位置的数还没比较过,所以不动)。

遍历完后,arr[r]和大于区的最左侧位置交换。

最后返回,此时小于区的后一个位置,大于区的位置,即是最后的等于arr[r]的左, 右下标值。

4、详细的参考代码

    /*** 荷兰国旗问题* <p>* 把数组arr中,[l, r]范围内的数,小于arr[r]放到数组最左边,等于arr[r]放到数组中间,大于arr[r]放到数组最右边** @return 返回等于arr[r]的左, 右下标值*/public static int[] netherlandsFlag(int[] arr, int l, int r) {if (l > r) {return new int[]{-1, -1};}if (l == r) {return new int[]{l, r};}// 小于arr[r]的右边界,从L的左边一位开始int less = l - 1;// 大于arr[r]的左边界,从r开始,即当前右边界里已经有arr[r]int more = r;// 当前正在比较的下标int index = l;// 不能与 大于arr[r]的左边界 撞上while (index < more) {if (arr[index] < arr[r]) {// 小于时,将当前位置的数和小于arr[r]的右边界的下一个位置交换// 当前位置后移一位swap(arr, index++, ++less);} else if (arr[index] == arr[r]) {// 等于时,当前位置后移一位即可index++;} else {// 大于时,当前位置的数和大于arr[r]的左边界的前一个位置交换// 当前位置不动swap(arr, index, --more);}}// 将arr[r]位置的数和大于arr[r]的左边界的数交换// 此时整个数组就按照 小于、等于、大于arr[r] 分成了左中右三块swap(arr, more, r);// 最后整个数组中,等于arr[r]的左右边界分别是less + 1, morereturn new int[]{less + 1, more};}

二、快速排序

1、啥是快排(排序流程)

首先设定一个分界值,通过该分界值将数组分成左中右三部分。

(1)将小于分界值的数据集中到数组的左边,等于分界值的数据集中到数组的中间,大于分界值的数据集中到数组右边。

(2)然后,左边和右边的数据可以独立排序。对于左侧的数据,又可以取一个分界值,将该部分数据分成左中右三部分,同样在左边放较小值,中间放等于值,右边放较大值。右边数据也做同样的处理。

(3)重复上述过程,可以看出,这是一个递归过程。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。

当看完了快排的流程,是不是发现快排的核心方法就是荷兰国旗问题,所以知道为啥本文一开始就介绍荷兰国旗问题了吧

2、抽象后的快排流程

(1)随机将数组中的某个数放到比较位置上(即最右侧位置)

(2)调用荷兰国旗方法,(此时等于区的数即在最后排好序的位置上),拿到等于区的左右下标

(3)小于区和大于区再各自递归调用(1)(2)步即可将小于区和大于区排好序。

3、详细的参考代码

    /*** 随机快排*/public static void quickSortRandom(int[] arr) {if (arr == null || arr.length < 2) {return;}processRandom(arr, 0, arr.length - 1);}private static void processRandom(int[] arr, int l, int r) {if (l >= r) {return;}// 随机将数组中的某个数放到比较位置上(即数组最右边位置)// 这一步是保证快排时间复杂度是O(N*logN)的关键,不然,快排的时间复杂度是O(N^2)swap(arr, l + (int) ((r - l + 1) * Math.random()), r);// 将数组划分为 小于、等于、大于arr[r] 的左中右三块int[] equalArea = netherlandsFlag(arr, l, r);// 此时等于区域的值已经处于最后排序结果的位置了// 递归将左半部分的排好序processRandom(arr, l, equalArea[0] - 1);// 递归将右半部分的排好序processRandom(arr, equalArea[1] + 1, r);}public static void swap(int[] arr, int i, int j) {int tmp = arr[i];arr[i] = arr[j];arr[j] = tmp;}

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

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

相关文章

拍卖理论 英式拍卖 和 荷兰式拍卖 是什么

拍卖理论 源自Vickrey&#xff08;1961&#xff09;的早期研究&#xff0c;其因此获得1996年的诺贝尔经济学奖。 目标一般为&#xff1a;拍卖人的收益最大化、社会的整体效率最优化 对科研和商业方面有非常价值 英式拍卖 又称增价拍卖。拍品的起拍价格即最低期望价格&#…

谈腾讯地图web api如何实现类似百度地图内置的城市切换、关键字输入提示功能

PC WEB端新增客户的时候需要填写客户地址和联系人信息&#xff0c;包括&#xff1a;省市区、街道、详细地址和经纬度以及联系人、固话和移动电话。获取客户地址信息之前用的是百度地图&#xff0c;由于小程序中客户拜访时&#xff0c;需要对客户进行定位、距离计算&#xff0c;…

数学系列 (二)自然数、分数、小数、算数、代数

从无到有 数的概念 出生不久的孩子你觉的他认识1、2、3类似的数字吗&#xff1f;应该都不知道&#xff0c;可见数字的概念也是随着我们人类成长逐渐认识到的&#xff0c;英国经济学创立者亚当斯密说“数是人类在精神上制造出来的最抽象的概念”&#xff0c;属于逻辑思维里面的…

html 省份,城市 选择器附效果图

开发交流QQ群: 173683895 173683895 526474645 人满的请加其它群 效果图&#xff1a; 源码&#xff1a; <!DOCTYPE html> <html><head><meta charset"UTF-8"><link href"https://cdn.bootcss.com/bootstrap/3.3.7/css/boots…

深圳前海和后海的地理位置划分

前海后海的地理位置 前海和后海主要是相对于珠江口而言的&#xff0c;面向珠江口的为前海&#xff0c;背向珠江口的为后海或面向深圳湾的为后海。 前海知识拓展 https://www.sohu.com/a/490380431_124752

Python实现天气查询功能(外加Excel技巧)

昨天在网上发现了一个非常方便的天气API&#xff0c;就用Python试着用了一下。参数是挺少的&#xff0c;用起来也方便&#xff0c;但是那个城市代码确实是搞了我好长时间。 一、介绍 我们先来看一下实现的程序有什么功能&#xff1a; 功能也是非常简单的&#xff0c;输入城市…

找零钱问题——贪心算法

蓝桥杯——算法训练——找零钱 有n个人正在饭堂排队买海北鸡饭。每份海北鸡饭要25元。奇怪的是&#xff0c;每个人手里只有一张钞票&#xff08;每张钞票的面值为25、50、100元&#xff09;&#xff0c;而且饭堂阿姨一开始没有任何零钱。请问饭堂阿姨能否给所有人找零&#xf…

c语言 贪心算法 找零钱,贪心算法-找零钱(C#实现)

找零钱这个问题很清楚,无非就是始终拿可以取的最大面值来找,最后就使得张数最小了,这个实现是在假设各种面值足够多的情况下。 首先拖出一个界面来,最下面是一个listbox控件 对应的代码:问题比较简单,有注释 using System; using System.Collections.Generic; using Syst…

仿秒秒测日历页面和部分功能

秒秒测&#xff1a; 这里的农历和宜忌我们用的是这个lunar类库 <?phprequire Lunar.php;use com\nlf\calendar\Foto; use com\nlf\calendar\LunarYear; use com\nlf\calendar\util\HolidayUtil; use com\nlf\calendar\Lunar; use com\nlf\calendar\Solar;// 实例化 $sol…

蓝桥杯-算法训练-找零钱

问题描述   有n个人正在饭堂排队买海北鸡饭。每份海北鸡饭要25元。奇怪的是&#xff0c;每个人手里只有一张钞票&#xff08;每张钞票的面值为25、50、100元&#xff09;&#xff0c;而且饭堂阿姨一开始没有任何零钱。请问饭堂阿姨能否给所有人找零&#xff08;假设饭堂阿姨足…

蓝桥杯全排列扩展(找零钱问题-java详解)

题目&#xff1a; 有n个人正在饭堂排队买海北鸡饭。每份海北鸡饭要25元。奇怪的是&#xff0c;每个人手里只有一张钞票&#xff08;每张钞票的面值为25、50、100元&#xff09;&#xff0c;而且饭堂阿姨一开始没有任何零钱。请问饭堂阿姨能否给所有人找零&#xff08;假设饭堂…

想搞钱,先培养商业思维!

昨天谈借助 ChatGPT 挣点房贷钱的时候&#xff0c;看评论区大家留言的时候&#xff0c;发现很多人不知道这个东西可以赚钱&#xff0c;或者说知道这个东西且也做了功课&#xff0c;无奈太忙最后也没搞到钱。 可以看到&#xff0c;大家的问题&#xff0c;归根于自己有没有商业思…

马云获聘香港大学荣誉教授;马斯克预计 2 个月内再次尝试发射星舰;​Rust 1.69.0 发布|极客头条...

「极客头条」—— 技术人员的新闻圈&#xff01; CSDN 的读者朋友们早上好哇&#xff0c;「极客头条」来啦&#xff0c;快来看今天都有哪些值得我们技术人关注的重要新闻吧。 整理 | 梦依丹 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 一分钟速览新闻点&#…

中科院发布多模态 ChatGPT,图片、语言、视频都可以 Chat ?中文多模态大模型力作...

进NLP群—>加入NLP交流群 夕小瑶科技说 原创作者 | 小戏、ZenMoore在 GPT-4 的发布报道上&#xff0c; GPT-4 的多模态能力让人印象深刻&#xff0c;它可以理解图片内容给出图片描述&#xff0c;甚至能在图片内容的基础上理解其中的隐喻或推断下一时刻的发展。 无疑&#xf…

有没有哪个瞬间,让你突然对ChatGPT感到失望? | AIGC实践

不知道你是否和我一样&#xff0c;在第一次使用ChatGPT输入Prompt&#xff0c;并得到答复的那一刻&#xff0c;都会忍不住地赞叹一句&#xff1a;握草。 但随着时间慢慢拉长&#xff0c;体验不断深入&#xff0c;想法也会慢慢改变…… 主题图 by Midjourney。Prompt&#xff1a…

Linux系统调用(2.哈工大OS实验二)

Linux系统调用与哈工大实验二 实验要求 此次实验的基本内容是&#xff1a;在Linux 0.11上添加两个系统调用&#xff0c;并编写两个简单的应用程序测试它们。 具体实验细节可以参考蓝桥云&#xff1a; https://www.lanqiao.cn/courses/115/learning/?id374&compatibility…

排好队,一个一个来:宫本武藏教你学队列(附各种队列源码)

文章目录 前言&#xff1a;理解“队列”的正确姿势一个关于队列的小思考——请求处理队列的两大“护法”————顺序队列和链式队列数组实现的队列链表实现的队列 循环队列关于开篇&#xff0c;你明白了吗&#xff1f;最后说一句 前言&#xff1a; 哈喽&#xff01;欢迎来到黑…

分享几个线上副业!!

线上副业 有哪些可以在线上运作就能赚取生活费的方式&#xff1f; 我这个暑假没有去打暑假工&#xff0c;因为疫情原因&#xff0c;一直待在家里&#xff0c;没有收入就不能出去玩&#xff0c;不能买漂亮衣服&#xff0c;就开始了一系列的线上兼职寻找&#xff0c;到处碰壁&…

学会Python如何去变现?副业月收入10000+了解一下

自学 Python 之后如果不去公司上班&#xff0c;自己一个人可以通过此技能挣什么钱&#xff1f; 逆天的Python&#xff0c;只要你掌握了相关技术&#xff0c;就可以靠它赚钱&#xff0c;具体怎么赚&#xff0c;我们来看看一位小哥哥的回答。 以我差不多四年的 Python 使用经验…

悟空问答赚钱副业项目,操作的好可月入10000+

我不知道你是否做过这种项目。这也是自媒体。如果你没有&#xff0c;你可以试试。收入不错。 有人可能会说悟空问答已经过时了。事实上&#xff0c;悟空问答每天仍能挣300元。好吧&#xff0c;我们已经取得了经验&#xff0c;在这里我们也与大家分享。 基本上&#xff0c;每个…