优选算法——分治(快排)

news2024/12/13 17:51:39

1. 颜色分类

题目链接:75. 颜色分类 - 力扣(LeetCode)

题目展示

题目分析:本题其实就要将数组最终分成3块儿,这也是后面快排的优化思路,具体大家来看下图。

这里我们上来先定义了3个指针,大家要注意3个指针的作用,3个指针在移动的过程中会将数组分成4部分,每一部分都有固定的性质,3个指针移动的过程中,保证指定部分的性质不变,就可以实现最终的结果。

当扫描到0的时候,我们要保证[0,left]区间全是0,那么我们先将left指针向前移动一步,然后将该位置的值与i位置的值进行交换,然后让i向后移动一步;

当扫描到1时,要保证[left,i-1]区间全为1,那么直接让i++即可;

当扫描到2时,我们要保证[right,n-1]区间全为2,那么首先right指针要先往左移动一步,然后将该位置的值与i位置的值进行交换,这里注意不能让i++,因为i一旦往后移动,待扫描的元素就会被跳过。

代码实现

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

2. 快速排序

题目链接:912. 排序数组 - 力扣(LeetCode)

题目展示

题目分析

这里我们要采用数组分三段的方式来实现快排,这是一种比较优秀的方法,可以将快排的效率接近于O(NlogN)。

代码实现

class Solution 
{
public:
    vector<int> sortArray(vector<int>& nums) 
    {
        srand(time(NULL));//种下随机数种子
        qsort(nums,0,nums.size()-1);
        return nums;    
    }
    void qsort(vector<int>& nums,int l,int r)
    {
        if(l>=r)
        {
            return;
        }
        //数组分三块儿
        int key=getRandom(nums,l,r);
        int i=l;
        int left=l-1;
        int right=r+1;
        while(i<right)
        {
            if(nums[i]<key)
            {
                swap(nums[++left],nums[i++]);
            }
            else if(nums[i]==key)
            {
                i++;
            }
            else
            {
                swap(nums[--right],nums[i]);
            }
        }
        //[1,left][left+1,right-1][right,r]
        qsort(nums,l,left);
        qsort(nums,right,r);
    }
    int getRandom(vector<int>& nums,int left,int right)
    {
        int r = rand();
        return nums[r%(right-left+1)+left];
    }
};

3. 数组中的第K个最大元素

题目链接:215. 数组中的第K个最大元素 - 力扣(LeetCode)

题目展示

题目分析:本题其实就是TOP-K问题,关于TOP-K问题,我们可以使用堆来解决,但是使用堆,时间复杂度为O(NlogN);本题要求时间复杂度为O(n),我们要利用快速选择算法来解决。

代码实现

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=getrandom(nums,l,r);
        int i=l;
        int left=l-1;
        int right=r+1;
        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 c=r-right+1;
        int b=right-left-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 getrandom(vector<int>& nums,int left,int right)
    {
        return nums[rand()%(right-left+1)+left];
    }
};

4. 库存管理(最小的K个数)

题目链接:LCR 159. 库存管理 III - 力扣(LeetCode)

题目展示

题目分析: 本题和上一题其实是类似的,稍微变化了一下,这次我们要返回的是一个数组。

代码实现

class Solution {
public:
    vector<int> inventoryManagement(vector<int>& stock, int cnt) 
    {
        srand(time(NULL));
        qsort(stock,0,stock.size()-1,cnt);
        return {stock.begin(),stock.begin()+cnt};
    }
    void qsort(vector<int>& stock,int l,int r, int cnt)
    {
        if(l>=r)
        {
            return;
        }
        int key=getrandom(stock,l,r);
        int i=l;
        int left=l-1;
        int right=r+1;
        while(i<right)
        {
            if(stock[i]<key)
            {
                swap(stock[++left],stock[i++]);
            }
            else if(stock[i]==key)
            {
                i++;
            }
            else
            {
                swap(stock[--right],stock[i]);
            }
        }
        int a=left-l+1;
        int b=right-left-1;
        if(a>cnt)
        {
            return qsort(stock,l,left,cnt);
        }
        else if(a+b>=cnt)
        {
            return;
        }
        else
        {
            return qsort(stock,right,r,cnt-a-b);
        }
    }
    int getrandom(vector<int>& stock,int left,int right)
    {
        return stock[rand()%(right-left+1)+left];
    }
};

5. 总结

本文为大家介绍了分治专题的其中一部分内容——快排和快速选择,这两种算法非常重要,需要重点掌握,在解题的同时,大家要感受分治的思想,将大问题转化为小问题,然后通过解决小问题最终解决大问题,最后,希望本文可以为大家带来帮助,感谢阅读!

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

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

相关文章

[Maven]下载安装、配置与简介

很多框架的下载使用的流程和思路是差不多的&#xff0c;这里以maven做详细介绍。 下载安装与配置变量 下载 首先&#xff0c;我们要使用maven&#xff0c;必须先下载它的相关文件。想要下载&#xff0c;我们可以直接搜索maven。找到它的官网。这里不绕弯子&#xff0c;直接给出…

Maven 安装配置(详细教程)

文章目录 一、Maven 简介二、下载 Maven三、配置 Maven3.1 配置环境变量3.2 Maven 配置3.3 IDEA 配置 四、结语 一、Maven 简介 Maven 是一个基于项目对象模型&#xff08;POM&#xff09;的项目管理和自动化构建工具。它主要服务于 Java 平台&#xff0c;但也支持其他编程语言…

【AI知识】人工智能、机器学习、深度学习的概念与联系

下图来自博客 机器学习和深度学习概念入门 &#xff0c;图中可明显看到人工智能、机器学习、深度学习三个概念的包含关系&#xff0c;下面简单介绍一下这三个概念已经它们之间的联系。 1. 人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09; 概念&#x…

BUUCTF Pwn bjdctf_2020_babystack2 题解

1.下载 checksec 64位 拖入IDA64 定位到main函数 以及后门函数 发现read需要读取输入——nbytes的数字来决定长度 同时nbytes是size_t类型 也就是无符号整型的 所以想到整数溢出漏洞 将nbytes设置为-1就会回绕&#xff0c;变成超大整数 从而实现栈溢出漏洞 exp&#xff1a…

微服务-01【续】

1.OpenFeign 上篇文章我们利用Nacos实现了服务的治理&#xff0c;利用利用RestTemplate实现了服务的远程调用。但是远程调用的代码太复杂了&#xff1a; 而且这种调用方式&#xff0c;与原本的本地方法调用差异太大&#xff0c;编程时的体验也不统一&#xff0c;一会儿远程调用…

中电金信携手中远海科,共启贸易金融数智新篇章

在数智化转型成为驱动经济社会高质量发展的新引擎背景下&#xff0c;“数智方案”栏目聚焦金融等国计民生重点行业场景&#xff0c;依托中电金信“源启筑基咨询引领应用重构”的产品及服务体系&#xff0c;输出市场洞察和行业解决方案、应用案例&#xff0c;旨在全面推动行业IT…

【前端】React快速构建登陆注册前后端全栈

近期更新完毕&#xff0c;建议关注、收藏&#xff01; 目录 快速入门 快速入门 前提&#xff1a;安装npm #npm install react react-dom conda install nodejs npm install create-react-app cd my-app#切换到项目文件夹 npm install npm i web-vitals --save-dev #如果上述…

JS中的原型链与继承

文章目录 原型链的类比原型链对像与函数拥有的原型属性不同原型链的产生对象的constructor属性继承 原型链的类比 JS中原型链&#xff0c;本质上就是对象之间的关系&#xff0c;通过protoype和[[Prototype]]属性建立起来的连接。这种链条是动态的&#xff0c;可以随时变更。 …

Ubuntu22.04搭建FTP服务器保姆级教程

在网络环境中&#xff0c;文件传输是一项至关重要的任务。FTP&#xff08;文件传输协议&#xff09;是一种基于客户端/服务器模式的协议&#xff0c;广泛用于在互联网上传输文件。Ubuntu作为一款流行的Linux发行版&#xff0c;因其稳定性和易用性而广受开发者和系统管理员的喜爱…

基于Kubesphere实现微服务的CI/CD——部署微服务项目(三)

目录 一、kubesphere安装 1、安装本地持久存储 1.1、default-storage-class.yaml 1.2、 openebs-operator.yaml 1.3、安装 Default StorageClass 2、安装kubesphere 2.1、安装Helm 2.2、安装kubesphere 二、配置kubesphere 1、安装插件 2、创建devops项目 3、配置…

jenkins harbor安装

Harbor是一个企业级Docker镜像仓库‌。 文章目录 1. 什么是Docker私有仓库2. Docker有哪些私有仓库3. Harbor简介4. Harbor安装 1. 什么是Docker私有仓库 Docker私有仓库是用于存储和管理Docker镜像的私有存储库。Docker默认会有一个公共的仓库Docker Hub&#xff0c;而与Dock…

open cv学习之图片矫正

一&#xff0c;实验原理 图像矫正的原理是透视变换 图像畸变主要有两类&#xff1a;径向畸变和切向畸变。径向畸变通常会导致图像的四个角向外或向内弯曲&#xff1b;切向畸变则是由于相机与图像平面不完全平行引起的。而OpenCV 提供了一个相机标定的工具&#xff0c;能够自动…

【再谈设计模式】组合模式~层次构建的多面手

一、引言 在软件开发的世界里&#xff0c;我们经常面临着处理对象之间复杂关系的挑战。如何有效地表示对象的部分 - 整体层次结构&#xff0c;并且能够以一种统一的方式操作这些对象&#xff0c;是一个值得探讨的问题。组合模式&#xff08;Composite Pattern&#xff09;为我们…

关于Git分支合并,跨仓库合并方式

关于Git合并代码的方式说明 文章目录 关于Git合并代码的方式说明前情提要开始合并方式一&#xff1a;git merge方式二&#xff1a;git cherry-pick方式三&#xff1a;git checkout Git跨仓库合并的准备事项前提拉取源仓库代码 前情提要 同仓库不同分支代码的合并可直接往下看文…

Android Freezer

Freezer原理 Android按照优先级将一般的APP从高到低分为: 前台进程 --> 可感知进程–> 服务进程 --> Cached进程。 Freezer通过冻住cached进程,来迫使这些进程让出CPU&#xff0c;以达到优化系统资源使用的目的。 Cached进程是怎么判定的呢&#xff1f; 由于andro…

websocker的java集成过程

第一步&#xff1a;引入依赖包 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dependency> 第二步设置配置类&#xff1a; // 需要注入Bean的话必须声明为配置类 Co…

设计模式:24、访问者模式

目录 0、定义 1、访问者模式的五种角色 2、访问者模式的UML类图 3、示例代码 0、定义 表示一个作用于某对象结构中的各个元素的操作。它可以在不改变各个元素的类的前提下&#xff0c;定义作用于这些元素的新操作。 1、访问者模式的五种角色 抽象元素&#xff08;Element…

umi实现动态获取菜单权限

文章目录 前景登录组件编写登录逻辑菜单的时机动态路由页面刷新手动修改地址 前景 不同用户拥有不同的菜单权限&#xff0c;现在我们实现登录动态获取权限菜单。 登录组件编写 //当我们需要使用dva的dispatch函数时&#xff0c;除了通过connect函数包裹组件还可以使用这种方…

Color-Light-Control-and-Four-Way-Responder based on STM32F103C8T6

Light Control and Responder 若要实现同样效果请看源码: gitee.com/apollo_666/Color-Light-Control-and-Four-Way-Responder # Abstract The design project for a decorative lighting controller enhanced our practical skills and engineering capabilities. During our…

数据库中的运算符

1.算术运算符 算术运算符主要用于数学运算&#xff0c;其可以连接运算符前后的两个数值或表达式&#xff0c;对数值或表达式进行加&#xff08;&#xff09;、减&#xff08;-&#xff09;、乘&#xff08;*&#xff09;、除&#xff08;/&#xff09;和取模&#xff08;%&…