刷题训练之分治快排

简介: 刷题训练之分治快排

> 作者:დ旧言~

> 座右铭:松树千年终是朽,槿花一日自为荣。

> 目标:熟练掌握分治快排算法。

> 毒鸡汤:学习,学习,再学习 ! 学,然后知不足。

> 专栏选自:刷题训练营

> 望小伙伴们点赞👍收藏✨加关注哟💕💕



🌟前言分析

       最早博主续写了牛客网130道题,这块的刷题是让同学们快速进入C语言,而我们学习c++已经有一段时间了,知识储备已经足够了但缺少了实战,面对这块短板博主续写刷题训练,针对性学习,把相似的题目归类,系统的刷题,而我们刷题的官网可以参考:


⭐知识讲解

基本思想:


这个算法在我们学习数据结构中八大排序之快排,但这个快排比起数据结构中的快排简单不少,这个算在C语言中我们也涉及到了,如果大家对这个算法比较陌生的话,可以参考下面两篇博客,一个是数据结构中的另一个是C语言中的:


数据结构:手撕各种排序

C语言:快快快快快快快快快快排


特点:

我们下面题目所采用的方法都是三路划分法思想,这也和我们的标题分治不谋而合。

大致做题流程:

做题前一定要先画图,在写代码,如果能自己画出图来写代码轻松不少。


🌙topic-->1

题目链接:1.分治快-



题目分析:

题目意思比较简单,把数组中的0  1  2排序。

算法原理:

  • 解法:采用三指针

图解:



细节处理:

left需要指向为 - 1,循环条件为 i < right.

代码演示:

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 swap(nums[--right],nums[i]);
        }
    }
};


🌙topic-->2

题目链接:2.排序数组



题目分析:

给你一个整数数组 nums,请你将该数组升序排列。(解法有很多,我们采用快速排序算法)

算法原理:

  • 解法:采用快速排序算法(三指针)

图解:



细节处理:

  • 递归结束标志是 l >= r

代码演示:

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,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]);
        }
 
        // 划分三个区域 [l ,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];
    }
};


🌙topic-->3

题目链接:3. 数组中的第K个最大元素



题目分析:

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。(你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。)


算法原理:

  • 解法:采用快速排序算法(三指针)

 图解:



细节处理:

  • 递归结束标志是 l == r

代码演示:

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


🌙topic-->4

题目链接:


 


题目分析:

输入整数数组 arr,找出其中最小的 k 个数。(跟上面的题目相似,这里不在细致讲解)

算法原理:

  • 解法:采用快速排序算法(三指针)

 图解:



细节处理:

  • 递归结束标志是 l >= r

代码演示:

class Solution
{
public:
  vector<int> getLeastNumbers(vector<int>&nums, int k)
  {
    srand(time(NULL));
    qsort(nums, 0, nums.size() - 1, k);
    return { nums.begin(), nums.begin() + k };
  }
  void qsort(vector<int>& nums, int l, int r, int k)
  {
    if (l >= r) return;
    // 1. 随机选择⼀个基准元素 + 数组分三块
    int key = getRandom(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]);
    }
    // [l, left][left + 1, right - 1] [right, r]
    // 2. 分情况讨论
    int a = left - l + 1, b = right - left - 1;
    if (a > k) qsort(nums, l, left, k);
    else if (a + b >= k) return;
    else qsort(nums, right, r, k - a - b);
  }
  int getRandom(vector<int>& nums, int l, int r)
  {
    return nums[rand() % (r - l + 1) + l];
  }
};


🌟结束语

      今天内容就到这里啦,时间过得很快,大家沉下心来好好学习,会有一定的收获的,大家多多坚持,嘻嘻,成功路上注定孤独,因为坚持的人不多。那请大家举起自己的小手给博主一键三连,有你们的支持是我最大的动力💞💞💞,回见。


目录
相关文章
|
人工智能 并行计算 PyTorch
【Hello AI】手动安装AIACC-Inference(AIACC推理加速)Torch版
AIACC-Inference(AIACC推理加速)支持优化基于Torch框架搭建的模型,能够显著提升推理性能。本文介绍如何手动安装AIACC-Inference(AIACC推理加速)Torch版并提供示例体验推理加速效果。
|
设计模式 缓存 JavaScript
JavaScript 简单实现观察者模式和发布-订阅模式
JavaScript 简单实现观察者模式和发布-订阅模式
237 0
|
JSON 数据格式
Charles自动保存响应数据
Charles自动保存响应数据
Charles自动保存响应数据
|
测试技术 程序员 C++
C++单元测试GoogleTest和GoogleMock十分钟快速上手(gtest&gmock)
gtest是Google开源的一个跨平台的(Liunx、Mac OS X、Windows等)的 C++ 单元测试框架,可以帮助程序员测试 C++ 程序的结果预期。它提供了丰富的断言、致命和非致命判断、参数化、”死亡测试”等等。另一方面,gmock并不是一个独立的测试框架,而是gtest的辅助框架,主要用于模拟没有实现的类的操作,以便在没有完整类的情况下进行测试。通过配合使用gtest和gmock,开发者可以编写出更为复杂且健壮的C++单元测试。
2010 0
|
Java 编译器 开发者
java中运行时异常与编译时异常?
java中运行时异常与编译时异常?
|
缓存 NoSQL 关系型数据库
数据传输服务的主要功能
【6月更文挑战第4天】数据传输服务的主要功能
412 3
|
机器学习/深度学习 边缘计算 算法
深度学习之进化神经网络设计
基于深度学习的进化神经网络设计(Evolutionary Neural Networks, ENNs)结合了进化算法(EA)和神经网络(NN)的优点,用于自动化神经网络架构的设计和优化。
509 1
|
JavaScript 前端开发 API
【Vue面试题三十一】、你是怎么处理vue项目中的错误的?
这篇文章讨论了Vue项目中错误的处理方式,包括后端接口错误和代码逻辑错误的处理策略。文章详细介绍了如何使用axios的拦截器处理后端接口错误,以及Vue提供的全局错误处理函数`errorHandler`和生命周期钩子`errorCaptured`来处理代码中的逻辑错误。此外,还分析了Vue错误处理的源码,解释了`handleError`、`globalHandleError`、`invokeWithErrorHandling`和`logError`函数的作用和处理流程。
【Vue面试题三十一】、你是怎么处理vue项目中的错误的?
|
前端开发 算法 JavaScript
如何优化前端性能:探索图片压缩与延迟加载技术
本文深入探讨了前端性能优化中的关键问题:图片压缩与延迟加载技术。通过介绍图片压缩的原理和方法,并结合实例说明了如何有效减少图片大小、提升加载速度;同时,详细解析了延迟加载技术的实现原理及其在提高页面加载性能中的作用,为前端开发者提供了实用的优化方案。
|
机器学习/深度学习 数据可视化 算法
数据科学家:解锁未来的关键技能集
【8月更文挑战第25天】成为一名优秀的数据科学家需要掌握多方面的技能,从统计学与数学基础到编程语言与数据处理能力,再到机器学习与深度学习、数据可视化与故事讲述,以及业务理解与领域知识,每一步都不可或缺。同时,保持持续学习与创新能力,紧跟时代步伐,才能在数据科学的道路上不断前行,为企业创造更大的价值。