【水调歌头·排序篇】--体验快排与归并的奥妙

快排算法篇

  • 一、快排
    • 1 .1颜色分类
    • 1.2数组中第k个最大元素
  • 二、归并排序
    • 2.1排序数组
    • 2.2翻转对
    • 2.3交换逆序对总数

在这里插入图片描述

一、快排

使用快排的思想就是 将一段区域分为3段,在选取一个基准元素key。让这三段分别小于key,等于key,大于key.

。。

1 .1颜色分类

颜色分类
在这里插入图片描述


由于本体只会出现3个数字,并且结果要求输出 0,1,2这样的。 很容易解出来。

这里使用的思想就是数组划分三段。定义3个指针,i指针遍历数组,left指针标记最左侧。right标记最右侧。
分类讨论,遍历时候 如果nums[i]是0的话,交换swap(nums[++left],nums[i]) 并且都向后移动;如果是1,不用交换,i++继续向后移动;如果是2,交换右边的跟当前的swap(nums[right–],nums[i]),此时i不用向后移动,继续对当前交换后的数进行判断。

在这里插入图片描述


代码片:

class Solution {
public:void sortColors(vector<int>& nums) {int n=nums.size();int left=-1,right=n,i=0;while(i<right){if(nums[i]==0)  swap(nums[++left],nums[i++]);else if(nums[i]==1) i++;else if(nums[i]==2) swap(nums[--right],nums[i]);}}
};

1.2数组中第k个最大元素

数组中的第k个最大元素

这里使用的快排的思想。我们先选个随机标准数key,根据key值将数组分三块,小于key值放最左边,等于key值放右边,大于key值放最右边。题目要求求第k大元素,这个k可能落在这三个其中某一块区域。我们得确定k落在哪个区域,我们设第一个区域元素有a个,第二个区域有b个,第三个区域有c个。如果c>=k,在【right,r】区间找第k大元素。(因为最右边都是大的元素,大的元素有c个,如果第k大比c小的话,那第k大元素一定落在该区域)。b+c>=k,返回key值。以上都不成立,就在第一个区间找第k-b-c大元素(因为我们要在整个区间找第k大元素,但是大元素都不是我们要的结果,接下来在这个小区间时候,要把大区间元素个数抛弃掉)。

草图:

在这里插入图片描述

代码篇:

class Solution {
public:int findKthLargest(vector<int>& nums, int k) {//快排srand(time(NULL));return qsort(nums,0,nums.size()-1,k);}int qsort(vector<int>& nums,int l,int r,int k){if(l==r)    return nums[l];//选随机标准数int key=getRodm(nums,l,r);int left=l-1,right=r+1,i=l;while(i<right){if(nums[i]<key)   swap(nums[++left],nums[i++]);else if(nums[i]==key)   i++;else swap(nums[--right],nums[i]);}//找出那个数int b=right-left-1,c=r-right+1;if(c>=k)  return qsort(nums,right,r,k);else if(b+c>=k)   return key;else return qsort(nums,l,left,k-b-c);}int getRodm(vector<int>& nums,int left,int right){int r=rand();return nums[r%(right-left+1)+left]; }
};

1.3

二、归并排序

归并排序,也用到了递归思想。一段区间,选取中间点,分别从左右两区间排序(根据题目要求决定升序降序),排序完之后合并俩有序数组,再返回上一层。在这里插入图片描述

2.1排序数组

排序数组
题目描述:
在这里插入图片描述


讲解篇:
本体讲解下归并的方法。我们将数组分为两部分。[left,mid] [mid+1,right].定义俩指针 cur1 、 cur2,分别指向两个区域的开始位置。因为这道题本身要求是返回一个升序数数列。所以我们直接在合并俩有序数组这一步处理,如果cur1小于cur2值,将nums[cur1]赋给新数组,然后cur1向后移动,移动到一个新数,再去比较。 否则,反之。最后将排序tmp中的数给到nums数组中。

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

代码篇:

class Solution 
{vector<int> tmp;
public:vector<int> sortArray(vector<int>& nums) {tmp.resize(nums.size());mergesort(nums,0,nums.size()-1);return nums;}void mergesort(vector<int>& nums,int left,int right){if(left>=right) return ;//选择中间点划分区间int mid=(left+right)>>1;//[left,mid],[mid+1,right]//2\把左右区间排序mergesort(nums,left,mid);mergesort(nums,mid+1,right);//3、合并两个有序数组int cur1=left,cur2=mid+1,i=0;while(cur1<=mid && cur2<=right){tmp[i++]=nums[cur1]<=nums[cur2]?nums[cur1++]:nums[cur2++];}//4处理没有遍历完的数组while(cur1<=mid)    tmp[i++]=nums[cur1++];while(cur2<=right)  tmp[i++]=nums[cur2++];//for(int i=left;i<=right;i++){nums[i]=tmp[i-left];}}
};

2.2翻转对

翻转对

本题的解题思路用到的是归并法。题目的意思是计算当前元素后面有多少数2倍比我还小。将该数组划分为两段,定义俩个区间的指针,先固定cur1,让cur2向后遍历,如果当前数2倍比cur1值大,继续向后遍历寻找。如果刚好比cur1小。那么cur2后面的数肯定也比cur1小。因为找的时候对数组降序排序了。剩下的操作都是归并排序里通用的思路。

在这里插入图片描述

class Solution {int tmp[50010];
public:int reversePairs(vector<int>& nums) {return mergesort(nums,0,nums.size()-1);}int mergesort(vector<int>& nums,int left,int right){if(left>=right) return 0;int res=0;//划分区间int mid=(left+right)>>1;res+=mergesort(nums,left,mid);res+=mergesort(nums,mid+1,right);int cur1=left,cur2=mid+1,i=left;//计算翻转对的数量while(cur1<=mid){while(cur2<=right&& nums[cur2]>=nums[cur1]/2.0)   cur2++;if(cur2>right)break;res+=right-cur2+1;cur1++;}//合并  降序cur1=left,cur2=mid+1;while(cur1<=mid&&cur2<=right){tmp[i++]=nums[cur1]<=nums[cur2]?nums[cur2++]:nums[cur1++];}//未处理完的时候while(cur1<=mid)    tmp[i++]=nums[cur1++];while(cur2<=right)  tmp[i++]=nums[cur2++];//还原数组for(int j=left;j<=right;j++){nums[j]=tmp[j];}return res;}
};

2.3交换逆序对总数

交换逆序对的总数
在这里插入图片描述

题目解析:
这里其实意思就是求数组中的逆序对个数。方法还是归并排序。

这里使用的是归并的思想。将一段数组分成两块进行分析(这俩块按升序排序)。定义俩指针cur1、cur2,分别指向left和right.一直遍历循环。找到该数之前,统计有多少个数比我大。当cur2当前的值比cur1当前的值大或者等于。说明cur2指向的值第一次比他大,cur1继续向后走, 当cur1指向的值比cur2大。找到该数了 并且cur1后面的值肯定都比cur2指向的值大。统计个数。然后继续向后走。直到不走出边界位置。

在这里插入图片描述

class Solution 
{vector<int>tmp;
public:int reversePairs(vector<int>& nums) {tmp.resize(nums.size());return mergesort(nums,0,nums.size()-1);}int  mergesort(vector<int>& nums,int left,int right){if(left>=right) return 0;int ret=0;int mid=(left+right)>>1;//左边的个数+排序+右边的个数+排序ret+=mergesort(nums,left,mid);ret+=mergesort(nums,mid+1,right);//一左一右的个数int cur1=left,cur2=mid+1,i=0;while(cur1<=mid && cur2<=right){if(nums[cur1]<=nums[cur2])  tmp[i++]=nums[cur1++];else{ret+=mid-cur1+1;tmp[i++]=nums[cur2++];}}//4、处理下排序while(cur1<=mid) tmp[i++]=nums[cur1++];while(cur2<=right)  tmp[i++]=nums[cur2++];//for(int j=left;j<=right;j++){nums[j]=tmp[j-left];}return ret;}
};

总结;
我们在写归并排序题时候会发现都会有相同之处。但是对于不同的题,具体问题得具体分析。归并排序的空间复杂度:O(n),因为在合并过程中需要额外的空间来存储临时数组。时间复杂度为O(n log n)

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

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

相关文章

【CV001】归一化互相关模板匹配matlab实现

Normalized Cross-Correlation (NCC) 的原理 Normalized Cross-Correlation (NCC) 是一种衡量两个信号或图像之间相似度的度量方法。它在图像处理、计算机视觉和信号处理等领域应用广泛&#xff0c;特别是在模板匹配&#xff08;template matching&#xff09;中。NCC 的目标是…

基于DeepSeek实现PDF嵌入SVG图片无损放大

1. PDF中效果图 2. 询问Deepseek进行代码书写&#xff0c;不断优化后结果 /*** SVG工具类&#xff0c;用于生成价格趋势的SVG图表*/ public class SvgUtils {// SVG画布尺寸private static final int WIDTH 800;private static final int HEIGHT 500;private static final i…

linyu-im

linyu-mini-server&#xff1a;springboot vue mysql。一款非常漂亮的linyu-im&#xff0c;它的mini版本&#xff0c;仅使用了mysql数据库 1、数据库有sqlite和mysql&#xff0c;这里修改为mysql 2、User类的badge徽章字段中使用了JacksonTypeHandler转为字符串为List<S…

提升数据库性能与可靠性:深入解析MySQL主从复制

在当今数据驱动的世界中&#xff0c;无论是初创公司还是大型企业&#xff0c;都面临着如何高效管理和保护其宝贵数据的挑战。随着业务的增长和用户需求的增加&#xff0c;单点数据库往往难以承受日益增长的负载压力&#xff0c;这就需要一种更加灵活、可靠的解决方案来确保系统…

【CVPR2025】 EVSSM:用状态空间模型高效去模糊

Efficient Visual State Space Model for Image Deblurring 论文信息 题目&#xff1a; Efficient Visual State Space Model for Image Deblurring 用于图像去模糊的高效视觉状态空间模型 源码&#xff1a;https://github.com/kkkls/EVSSM 创新点 提出了高效视觉状态空间模型…

Ubuntu虚拟机中使用QEMU搭建ARM64环境

Ubuntu虚拟机中使用QEMU搭建ARM64环境 通过本实验学习如何编译一个 ARM64 版本的内核 image&#xff0c;并且在QEMU 上运行起来。 文章目录 Ubuntu虚拟机中使用QEMU搭建ARM64环境一、安装aarch64交叉编译工具二、安装QEMU三、制作根文件系统1、根文件系统简介2、BusyBox构建根…

SQL经典查询

查询不在表里的数据&#xff0c;一张学生表&#xff0c;一张学生的选课表&#xff0c;要求查出没有选课的学生&#xff1f; select students.student_name from students left join course_selection on students.student_idcourse_selection.student_id where course_selecti…

【神经网络】python实现神经网络(一)——数据集获取

一.概述 在文章【机器学习】一个例子带你了解神经网络是什么中&#xff0c;我们大致了解神经网络的正向信息传导、反向传导以及学习过程的大致流程&#xff0c;现在我们正式开始进行代码的实现&#xff0c;首先我们来实现第一步的运算过程模拟讲解&#xff1a;正向传导。本次代…

黑金风格人像静物户外旅拍Lr调色教程,手机滤镜PS+Lightroom预设下载!

调色教程 针对人像、静物以及户外旅拍照片&#xff0c;运用 Lightroom 软件进行风格化调色工作。旨在通过软件中的多种工具&#xff0c;如基本参数调整、HSL&#xff08;色相、饱和度、明亮度&#xff09;调整、曲线工具等改变照片原本的色彩、明度、对比度等属性&#xff0c;将…

Kubernetes中的 iptables 规则介绍

#作者&#xff1a;邓伟 文章目录 一、Kubernetes 网络模型概述二、iptables 基础知识三、Kubernetes 中的 iptables 应用四、查看和调试 iptables 规则五、总结 在 Kubernetes 集群中&#xff0c;iptables 是一个核心组件&#xff0c; 用于实现服务发现和网络策略。iptables 通…

C语言_数据结构总结5:顺序栈

纯C语言代码&#xff0c;不涉及C 想了解链式栈的实现&#xff0c;欢迎查看这篇文章&#xff1a;C语言_数据结构总结6&#xff1a;链式栈-CSDN博客 这里分享插入一下个人觉得很有用的习惯&#xff1a; 1. 就是遇到代码哪里不理解的&#xff0c;你就问豆包&#xff0c;C知道&a…

STM32之ADC

逐次逼近式ADC&#xff1a; 左边是8路输入通道&#xff0c;左下是地址锁存和译码&#xff0c;可将通道的地址锁存进ADDA&#xff0c;ADDB&#xff0c;ADDC类似38译码器的结构&#xff0c;ALE为锁存控制键&#xff0c;通道选择开关可控制选择单路或者多路通道&#xff0c;DAC为…

Magento2根据图片文件包导入产品图片

图片包给的图片文件是子产品的图片&#xff0c;如下图&#xff1a;A104255是主产品的sku <?php/*** 根据图片包导入产品图片&#xff0c;包含子产品和主产品* 子产品是作为主图&#xff0c;主产品是作为附加图片*/use Magento\Framework\App\Bootstrap;include(../app/boot…

初学STM32之简单认识IO口配置(学习笔记)

在使用51单片机的时候基本上不需要额外的配置IO&#xff0c;不过在使用特定的IO的时候需要额外的设计外围电路&#xff0c;比如PO口它是没有内置上拉电阻的。因此若想P0输出高电平&#xff0c;它就需要外接上拉电平。&#xff08;当然这不是说它输入不需要上拉电阻&#xff0c;…

图像生成-ICCV2019-SinGAN: Learning a Generative Model from a Single Natural Image

图像生成-ICCV2019-SinGAN: Learning a Generative Model from a Single Natural Image 文章目录 图像生成-ICCV2019-SinGAN: Learning a Generative Model from a Single Natural Image主要创新点模型架构图生成器生成器源码 判别器判别器源码 损失函数需要源码讲解的私信我 S…

STM32之I2C硬件外设

注意&#xff1a;硬件I2C的引脚是固定的 SDA和SCL都是复用到外部引脚。 SDA发送时数据寄存器的数据在数据移位寄存器空闲的状态下进入数据移位寄存器&#xff0c;此时会置状态寄存器的TXE为1&#xff0c;表示发送寄存器为空&#xff0c;然后往数据控制寄存器中一位一位的移送数…

Git - 补充工作中常用的一些命令

Git - 补充工作中常用的一些命令 1 一些场景1.1 场景11.2 场景21.3 场景31.4 场景41.5 场景51.6 场景61.7 场景71.8 场景81.9 场景91.10 场景101.11 场景111.12 场景121.13 场景131.14 场景141.15 场景15 2 git cherry-pick \<commit-hash\> 和 git checkout branch \-\-…

AI 驱动的软件测试革命:从自动化到智能化的进阶之路

&#x1f680;引言&#xff1a;软件测试的智能化转型浪潮 在数字化转型加速的今天&#xff0c;软件产品的迭代速度与复杂度呈指数级增长。传统软件测试依赖人工编写用例、执行测试的模式&#xff0c;已难以应对快速交付与高质量要求的双重挑战。人工智能技术的突破为测试领域注…

Unity--Cubism Live2D模型使用

了解LIVE2D在unity的使用--前提记录 了解各个组件的作用 Live2D Manuals & Tutorials 这些文件都是重要的控制动画参数的 Cubism Editor是编辑Live2D的工具&#xff0c;而导出的数据的类型&#xff0c;需要满足以上的条件 SDK中包含的Cubism的Importer会自动生成一个Pref…

Windows 系统 Docker Desktop 入门教程:从零开始掌握容器化技术

文章目录 前言一、Docker 简介二、Docker Desktop 安装2.1 系统要求2.2 安装步骤 三、Docker 基本概念四、Docker 常用命令五、实战&#xff1a;运行你的第一个容器5.1 拉取并运行 Nginx 容器5.2 查看容器日志5.3 停止并删除容器 六、总结 前言 随着云计算和微服务架构的普及&…