【算法】分治-快排

这篇具有很好参考价值的文章主要介绍了【算法】分治-快排。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

个人主页 : zxctscl
如有转载请先通知

前言

分治就是分而治之

1. 75. 颜色分类

【算法】分治-快排,算法,算法,排序算法,c++,数据结构

1.1 分析

就是把数组中的元素分为三块,0全部在左边,1全部在中间,2全部在右边。
这里要用到三个指针,一个i指针用来遍历,一个left用来存放0区域的最后侧,一个用来存放2区域的最左侧。
那么区间就分成了4个
【算法】分治-快排,算法,算法,排序算法,c++,数据结构
只需要判断nums[i]的值是什么,然后把它放在对应区域。把数组遍历一遍就行,最终i只要等于right就结束遍历,此时中间已经没有要确定区域的数了。
【算法】分治-快排,算法,算法,排序算法,c++,数据结构

1.2 代码

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int left=-1,right=nums.size(),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. 排序数组

【算法】分治-快排,算法,算法,排序算法,c++,数据结构

2.1 分析

可以先选择一个元素作为基准,把比它小的元素都放在它的左边,把它大的都放在右边,中间放的数就和它相等,这样数组就分为三个区间,递归找一下左边,再递归找一下右边,直到数组全部被排好。
【算法】分治-快排,算法,算法,排序算法,c++,数据结构

为了减少时间复杂度,选取基准值的时候选取随机数。
【算法】分治-快排,算法,算法,排序算法,c++,数据结构

2.2 代码

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 k=getRandom(nums,l,r);
        int i=l,left=l-1,right=r+1;
         while(i<right)
        {      
            if(nums[i]<k)
            {
                swap(nums[++left],nums[i++]);
            }
           else if(nums[i]==k)i++;
           else{
            swap(nums[--right],nums[i]);
           }
        }
        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. 215. 数组中的第K个最大元素

【算法】分治-快排,算法,算法,排序算法,c++,数据结构

3.1 分析

和上面那题一样,这里也将区间分三块。
随机选取一个基准元素k,根据这个基准元素将区间分三部分,左边都是小于k的,中间都是等于k的,有边都是大于k的。
题目要求找到的是第k大元素,那么在三个区域都有可以,但是如果确定这个第k大元素是在某一个区域的时候,那么剩下的两个区域就都不用考虑。
左边元素个数为a,中间为b,右边为c。
第一种如果在c区域,那么c大于等于k的,因为c区域放的是是大值区域,如果存在第k大的,那么最有可能就在c中,只需要c大于等于k就一定在。
在第二种情况找的时候,就说明第一种情况不存在,在中间的区域,那么就直接返回k就行,因为中间元素都是相等的。
第三种情况,前面两种情况都不存在,那么就在左边区间找,右边区域和中间区域都没有,那么找的就是第k-b-c大的元素。

【算法】分治-快排,算法,算法,排序算法,c++,数据结构

3.2 代码

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

4. LCR 159. 库存管理 III

【算法】分治-快排,算法,算法,排序算法,c++,数据结构

4.1 分析

解法一:
可以直接排序,把前面的cnt个数重新放在一个vector表里面返回就行。

解法二:用快速选择算法
就是前面所提到的随机选择基准元素k,把数组分三个区间。
【算法】分治-快排,算法,算法,排序算法,c++,数据结构
然后统计每一个区间的个数,此时就分为三种情况:
第一种情况:第k小,如果a>k就先从第一个区间找。
第二种情况:a+b大于等于k,那么就直接返回k就行,这个区间值都是相等的。
第三种情况:前面两种情况都不成立,说明这个k在右边这个区域,找k-a-b个元素就可以。

【算法】分治-快排,算法,算法,排序算法,c++,数据结构

4.2 代码

解法一:

class Solution {
public:
    vector<int> inventoryManagement(vector<int>& stock, int cnt) {
    sort(stock.begin(),stock.end());
    vector<int> v;
    for(int i=0;i<cnt;i++)
    {
        v.push_back(stock[i]);
    }
    return v;
    }
};

解法二:

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 k)
   {
       if(l>=r)return;
       int key=getRandom(stock,l,r);
       int i=l,left=l-1,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,b=right-left-1;
        if(a>k)qsort(stock,l,left,k);
        else if(a+b>=k) return;
        else  qsort(stock,right,r,k-a-b); 
         }

      int getRandom(vector<int>&stock,int left,int right)
     {
        int r=rand();
        return stock[r%(right-left+1)+left];
     }
    
};

有问题请指出,大家一起进步!!!文章来源地址https://www.toymoban.com/news/detail-857302.html

到了这里,关于【算法】分治-快排的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构与算法之分治法

    分治法首先需要明白递归的概念: 递归: 是指子程序直接调用自己或者通过一系列调用语句间接调用自己,是一种描述问题和解决问题的常用方法。递归的两个基本要素: 1.边界条件:也就是递归终止调用的条件。 2.递归出口:递归表达式,大问题分解为小问题。 分治算法的一

    2024年02月09日
    浏览(37)
  • DSt:数据结构的最强学习路线之数据结构知识讲解与刷题平台、刷题集合、问题为导向的十大类刷题算法(数组和字符串、栈和队列、二叉树、堆实现、图、哈希表、排序和搜索、动态规划/回溯法/递归/贪心/分治)总

    Algorithm:【算法进阶之路】之算法面试刷题集合—数据结构知识和算法刷题及其平台、问题为导向的十大类刷题算法(数组和字符串、链表、栈和队列、二叉树、堆、图、哈希表、排序和搜索、回溯算法、枚举/递归/分治/动态规划/贪心算法)总结 目录 相关文章

    2024年02月08日
    浏览(56)
  • 算法分析与设计考前冲刺 (算法基础、数据结构与STL、递归和分治、 动态规划、贪心算法、 回溯算法)

    算法分析与设计考前冲刺 算法基础 算法是一系列解决问题的清晰指令,代表着用系统的方法描述解决问题的策略机制。 程序是算法用某种程序设计语言的具体的 具体实现 算法特征: 有穷性(有限步) 确定性 输入 输出 可行性(有限时间) 算法的复杂性: 时间复杂性 和空间复

    2024年02月02日
    浏览(44)
  • 【算法】分治-快排

    个人主页 : zxctscl 如有转载请先通知 分治就是分而治之 就是把数组中的元素分为三块,0全部在左边,1全部在中间,2全部在右边。 这里要用到三个指针,一个i指针用来遍历,一个left用来存放0区域的最后侧,一个用来存放2区域的最左侧。 那么区间就分成了4个 只需要判断

    2024年04月25日
    浏览(30)
  • 快排算法(分治法)

            相信很多人接触到的第一个排序就是冒泡排序,冒泡排序是一种拿一个数依次和后面进行比较,这样也就确保了每一次排序之后不论降序还是升序这一个数都会在末尾或者最前端,那么今天我们要将的是快速排序,基于冒泡排序的改进版本,为什么说是改进呢。要

    2024年02月16日
    浏览(32)
  • 【算法系列篇】分治-快排

    我相信看到这里很多人都学过八大排序了吧,其中快速排序是一种非常高效的排序方式,那么今天我们将会使用快速排序的算法来解决实际生活中的某些问题。 分治算法是一种算法设计策略,它将大问题分解成更小的子问题,并通过解决子问题来解决原始问题。分治算法的基

    2024年02月10日
    浏览(34)
  • 数据结构——排序算法——归并排序

    在第二个列表向第一个列表逐个插入的过程中,由于第二个列表已经有序,所以后续插入的元素一定不会在前面插入的元素之前。在逐个插入的过程中,每次插入时,只需要从上次插入的位置开始,继续向后寻找插入位置即可。这样一来,我们最多只需要将两个有序数组遍历

    2024年02月09日
    浏览(47)
  • 【排序算法】数据结构排序详解

    前言: 今天我们将讲解我们数据结构初阶的最后一部分知识的学习,也是最为“炸裂”的知识---------排序算法的讲解!!!! 排序 :所谓排序,就是使一串记录,按照其中的某个或某些的大小,递增或递减的排列起来的操作。 稳定性 :假定在待排序的记录序列中,

    2023年04月08日
    浏览(50)
  • 数据结构和算法笔记4:排序算法-归并排序

    归并排序算法完全遵循分治模式。直观上其操作如下: 分解:分解待排序的n个元素的序列成各具n/2个元素的两个子序列。 解决:使用归并排序递归地排序两个子序列。 合并:合并两个已排序的子序列以产生已排序的答案。 我们直接来看例子理解算法的过程,下面是要排序

    2024年01月21日
    浏览(64)
  • 【数据结构与算法】十大经典排序算法-希尔排序

    🌟 个人博客: www.hellocode.top 🏰 Java知识导航: Java-Navigate 🔥 CSDN: HelloCode. 🌞 知乎 :HelloCode 🌴 掘金 :HelloCode ⚡如有问题,欢迎指正,一起学习~~ 希尔排序是一种插入排序的改进版本,旨在解决插入排序在处理大规模数据时的效率问题。通过将数组分为多个子序列并对

    2024年02月12日
    浏览(80)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包