【优选算法---分治】快速排序三路划分(颜色分类、快速排序、数组第K大的元素、数组中最小的K个元素)

一、颜色分类

题目链接:

75. 颜色分类 - 力扣(LeetCode)

题目介绍:

给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地 对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

必须在不使用库内置的 sort 函数的情况下解决这个问题。

  • n == nums.length
  • 1 <= n <= 300
  • nums[i] 为 01 或 2
思路:

这个题目的要求其实就是将0放到最左边,将1放到中间将2放到最后边,思路就是将数组划分为三个部分

设数组大小为 n ,定义三个指针 left, cur, right :
cur 往后扫描的过程中,保证:
  • [0, left)内的元素都是
  • [left , cur - 1] 内的元素都是 1
  • [cur, right] 内的元素是待定元素;
  • (right, n] 内的元素都是 2

当cur遍历到0,交换nums[cur]和nums[left],由于交换前left所指元素一定是1,所以cur和left都可以++。

当cur遍历到1,cur++;

当cur遍历到2,交换nums[cur]和nums[right],right可以--,但是由于交换前right所指元素依旧是待定元素,所以cur不能++,还要判断一下

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

二、快速排序

题目链接:

912. 排序数组 - 力扣(LeetCode)

题目介绍:

给你一个整数数组 nums,请你将该数组升序排列。

你必须在 不使用任何内置函数 的情况下解决问题,时间复杂度为 O(nlog(n)),并且空间复杂度尽可能小。

  • 1 <= nums.length <= 5 * 10^4
  • -5 * 104 <= nums[i] <= 5 * 10^4
思路:

与上面的题思路相同,不过我们需要先选择一个基准元素,让这个基准元素左边都是小于他的值,右边都是大于他的值,这样这个基准元素在数组中就排序好了。接下来就是排序左边的区间和右边的区间。

注意,数组中选择的那个基准元素可能存在很多个,一轮排序后 [left,right] 区间都是key,所以这段区间都不需要排序了,只需要排【begin,left-1】和【right+1,end】区间。

假设一个数组全是一样的值,这样三路划分的效率就很块,因为cur就会不断向后遍历,直到碰到right(end),其效率就是O(N)

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        qsort(nums,0,nums.size()-1);
        return nums;
    }
    void qsort(vector<int>& nums, int begin, int end) {
        // 进了这个区间一定能找到
        if (begin >= end)
            return;
        int key = nums[begin];
        int left = begin;
        int right = end;

        int cur = left + 1;
        // 分成三块
        while (cur <= right) {
            if (nums[cur] < key) {
                swap(nums[left++], nums[cur++]);
            } else if (nums[cur] == key) {
                cur++;
            } else {
                swap(nums[right--], nums[cur]);
            }
        }
        qsort(nums, begin, left - 1);
        qsort(nums, right + 1, end);
    }
};

三、数组的第K个最大元素

题目链接:

215. 数组中的第K个最大元素 - 力扣(LeetCode)

题目介绍:

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。

  • 1 <= k <= nums.length <= 105
  • -104 <= nums[i] <= 10
思路:

首先我们可以选择一个基准元素,采用三路划分排序一遍,此时 key的位置就排序好了,虽然此时他的左右两边都是无序的,但是此时我们可以判断一下,如果右边的元素个数大于等于k,那说明第k大的元素就在右边,那我们就不用管左边了,如果中间的元素加上右边的元素才大于等于k,那说明第k大的元素就是key,否则我们就到左边找第( k-右边元素数量-中间元素数量)大的元素,这样的算法是非常快的,因为我们不需要将数组完全的排好序。

其次,只要进入到了某个区间找元素,那就说明这值一定在这个区间中,所以当begin>=end时我们就可以返回nums[begin]

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        return qsort(nums,0,nums.size()-1,k);
    }

    int qsort(vector<int>& nums,int begin,int end,int k)
    {
        //进了这个区间一定能找到
        if(begin>=end)return nums[begin];

        int key=nums[begin];
        int left=begin;
        int right=end;

        int cur=left+1;
        //分成三块
        while(cur<=right)
        {
            if(nums[cur]<key)
            {
                swap(nums[left++],nums[cur++]);
            }
            else if(nums[cur]==key)
            {
                cur++;
            }
            else
            {
                swap(nums[right--],nums[cur]);
            }
        }
        int c=end-right;
        int b=right-left+1;
        if(c>=k)return qsort(nums,right+1,end,k);
        else if(b+c>=k)return key;
        else return qsort(nums,begin,left-1,k-b-c);
    }
};

四、数组中最小的k个数

题目链接:

LCR 159. 库存管理 III - 力扣(LeetCode)

题目介绍:

仓库管理员以数组 stock 形式记录商品库存表,其中 stock[i] 表示对应商品库存余量。请返回库存余量最少的 cnt 个商品余量,返回 顺序不限

思路:

与上一题的思路一样,我们先选择一个基准元素采用三路划分,将数组分为左中右三部分,如果左边的数量大于等于k,那说明最小的k个数就在左边,就到左边找,中间和右边不管了。如果左边和中间加起来的数量才大于等于k,那就可以直接返回,因为前k个元素已经在左边和中间了,虽然他们不是完全有序的。否则的话,我们就要到右边找最小的(k-a-b)个数了

class Solution {
public:
    vector<int> inventoryManagement(vector<int>& nums, int k) {
        qsort(nums,0,nums.size()-1,k);
        return {nums.begin(),nums.begin()+k};
    }
    void qsort(vector<int>& nums,int begin,int end,int k)
    {
        if(begin>=end) return;

        int key=nums[begin];

        int left=begin,right=end;
        int cur=left+1;
        //分为三块
        while(cur<=right)
        {
            if(nums[cur]<key)
            swap(nums[left++],nums[cur++]);
            else if(nums[cur]==key)
            cur++;
            else
            swap(nums[right--],nums[cur]);
        }
        // 判断
        int a=left-begin;
        int b=right-left+1;

        if(a>=k) qsort(nums,begin,left-1,k);
        else if(a+b>=k) return;
        else qsort(nums,right+1,end,k-a-b);
    }
};

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

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

相关文章

【译】仅有 Text2SQL 是不够的: 用 TAG 统一人工智能和数据库

原文地址&#xff1a;Text2SQL is Not Enough: Unifying AI and Databases with TAG 摘要 通过数据库为自然语言问题提供服务的人工智能系统有望释放出巨大的价值。此类系统可让用户利用语言模型&#xff08;LM&#xff09;的强大推理和知识能力&#xff0c;以及数据管理系统…

leetcode 面试经典 150 题:长度最小的子数组

链接长度最小的子数组题序号209题型数组解题方法滑动窗口难度中等 题目 给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl1, …, numsr-1, numsr] &#xff0c;并返回其长度。如果不存在符合条件…

vue 设置 VUE_APP_TITLE 打包部署后不生效

VUE_APP_TITLE 名门望族云科技有限公司网站 这里的 名门望族云科技有限公司网站 两边不能加 (单引号) 部署后,浏览器刷新网站根目录

经济研究复刻:企业ESG表现与创新(2009-2023年)

参照方先明&#xff08;2023&#xff09;的做法&#xff0c;对来自经济研究《企业ESG表现与创新—来自A股上市公司的证据》一文中的基准回归部分进行复刻。论文基于利益相关者理论分析了ESG表现对企业创新可能的影响及机制&#xff0c;利用2009-2023年A股上市公司的专利数据&am…

ECharts 手势框选方案:实现鼠标自由刷选区域,定向放大图表(文末附源码)

一. 背景 在 ECharts 中&#xff0c;图表开发属于最基础的组件开发&#xff0c;适合统计展示各种各样的数据&#xff0c;使用图形化的效果将海量数据直观的展示给用户&#xff0c;以便于让用户能够快速获取到数据展示及走向。但随着用户需求的不断迭代&#xff0c;我们最近的一…

卡尔曼滤波器的实用方法及其实现方法

前言 卡尔曼滤波器对于不熟悉的人来说就是一种算法,它使用随时间观察的一系列观量值,,加速度计和陀螺仪在测量值是就会包含测量误差的噪声.卡尔曼滤波器将尝试根据当前和以前的状态来估计系统的状态,这往往比测量更加的精准.问题在于机器人来回的移动,加速度计在用于测量重力加…

QScreen在Qt5.15与Qt6.8版本下的区别

简述 QScreen主要用于提供与屏幕相关的信息。它可以获取有关显示设备的分辨率、尺寸、DPI&#xff08;每英寸点数&#xff09;等信息。本文主要是介绍Qt5.15与Qt6环境下&#xff0c;QScreen的差异&#xff0c;以及如何判断高DPI设备。 属性说明 logicalDotsPerInch&#xff1…

0004.基于springboot+elementui的在线考试系统

适合初学同学练手项目&#xff0c;部署简单&#xff0c;代码简洁清晰&#xff1b; 愿世界和平再无bug 一、系统架构 前端&#xff1a;vue| elementui 后端&#xff1a;springboot | mybatis-plus 环境&#xff1a;jdk1.8 | mysql | maven 二、登录角色 1.管理员 2.老师 …

【Laravel】端口问题导致菜单打不开

以下是修改 Laravel 应用程序的端口配置&#xff0c; 修改环境变量 APP_URL 来实现 app/Providers/AppServiceProvider.php <?phpnamespace App\Providers;use Illuminate\Events\Dispatcher; use Illuminate\Support\ServiceProvider; use Illuminate\Support\Facades\URL…

【数据分析】数据结构数据内容概述

文章目录 表格结构数据特征数据类别结构化数据表格结构数据层级表格结构的数据类型单元格的格式属性 表格结构数据获取方法从企业后台数据库系统获取后台数据库系统获取数据流程前端操作平台获取从企业外部渠道获取数据 表格结构数据使用方法单元格值的引用方法单元格区域值的引…

makefile文件

简介&#xff1a; 自动化编译&#xff1a;只需要一个make命令&#xff0c;整个工程自动编译 提高编译效率&#xff1a;再次编译时&#xff0c;只编译修改的文件&#xff08;查看时间戳&#xff0c;根据修改文件的时间判断文件是否被修改&#xff09; 基本语法&#xff1a; …

STM32-笔记3-驱动蜂鸣器

1、复制03项目&#xff0c;重命名为04项目 打开04项目的Drivers/BSP/led文件夹&#xff0c;把led文件夹更改为beep文件夹&#xff0c;改文件夹内部的.c和.h文件更改为beep.c和beep.h文件&#xff0c;如下图所示。 2、打开工程文件 出现弹窗&#xff0c;显示找不到xx文件&#…

阿尔茨海默症数据集,使用yolo,voc,coco格式对2013张原始图片进行标注,可识别轻微,中等和正常的症状

阿尔茨海默症数据集,使用yolo&#xff0c;voc&#xff0c;coco格式对2013张原始图片进行标注&#xff0c;可识别轻微&#xff0c;中等&#xff0c;严重和正常的症状 数据集分割 训练组100&#xff05; 2013图片 有效集&#xff05; 0图片 测试集&#xf…

uniapp v-tabs修改了几项功能,根据自己需求自己改

根据自己的需求都可以改 这里写自定义目录标题 1.数组中的名字过长&#xff0c;导致滑动异常2.change 事件拿不到当前点击的数据&#xff0c;通过index在原数组中查找得到所需要的id 各种字段麻烦3.添加指定下标下新加红点显示样式 1.数组中的名字过长&#xff0c;导致滑动异常…

k8s kubernetes

文章目录 CGroupk8s运行时k8s组件k8s组件安装kubeadm命令kubectl命令k8s官网代码 CGroup 在 Linux 上&#xff0c;控制组&#xff08;CGroup&#xff09;用于限制分配给进程的资源。kubelet 和底层容器运行时都需要对接控制组来强制执行 为 Pod 和容器管理资源 并为诸如 CPU、…

学习笔记072——Java中的【JUC 并发编程】

文章目录 JUC 并发编程1、什么是高并发2、Java 实现多线程的第三种方式3、sleep 和 wait 方法的区别4、synchronized 锁定的是谁&#xff1f;5、ConcurrentModificationException6、JUC 工具类7、读写锁8、线程池 JUC 并发编程 JUC 是指 Java 并发编程工具包 java.util.concu…

【报错解决】vsvars32.bat 不是内部或外部命令,也不是可运行的程序或批处理文件

报错信息&#xff1a; 背景问题&#xff1a;Boost提示 “cl” 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件时&#xff0c;   按照这篇博客的方法【传送】添加了环境变量后&#xff0c;仍然报错&#xff1a; 报错原因&#xff1a; vsvars32.bat 的路径不正…

简单配置,全面保护:HZERO审计服务让安全触手可及

HZERO技术平台&#xff0c;凭借多年企业资源管理实施经验&#xff0c;深入理解企业痛点&#xff0c;为您提供了一套高效易用的审计解决方案。这套方案旨在帮助您轻松应对企业开发中的审计挑战&#xff0c;确保业务流程的合规性和透明度。 接下来&#xff0c;我将为大家详细介绍…

使用nvm对node进行多版本管理

1.nvm下载及安装 下载链接 下载完成后&#xff0c;对文件进行解压安装&#xff0c;按照提示一步步安装&#xff0c;如果电脑上之前有安装过node&#xff0c;需要先卸载&#xff0c;再进行安装。 按照提示完成安装。 2.设置环境变量 可以现在C:\Users\name\AppData\Roamin…

【JavaEE初阶】JavaScript相应的WebAPI

目录 &#x1f332;WebAPI 背景知识 &#x1f6a9;什么是 WebAPI &#x1f6a9;什么是 API &#x1f38d;DOM 基本概念 &#x1f6a9;什么是 DOM &#x1f6a9;DOM 树 &#x1f340;获取元素 &#x1f6a9;querySelector &#x1f6a9;querySelectorAll &#x1f384…