刷题训练之分治快排

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

> 作者:დ旧言~

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

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

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

> 专栏选自:刷题训练营

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



🌟前言分析

       最早博主续写了牛客网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版并提供示例体验推理加速效果。
|
JSON 数据格式
Charles自动保存响应数据
Charles自动保存响应数据
Charles自动保存响应数据
|
测试技术 程序员 C++
C++单元测试GoogleTest和GoogleMock十分钟快速上手(gtest&gmock)
gtest是Google开源的一个跨平台的(Liunx、Mac OS X、Windows等)的 C++ 单元测试框架,可以帮助程序员测试 C++ 程序的结果预期。它提供了丰富的断言、致命和非致命判断、参数化、”死亡测试”等等。另一方面,gmock并不是一个独立的测试框架,而是gtest的辅助框架,主要用于模拟没有实现的类的操作,以便在没有完整类的情况下进行测试。通过配合使用gtest和gmock,开发者可以编写出更为复杂且健壮的C++单元测试。
1466 0
|
Java 编译器 开发者
java中运行时异常与编译时异常?
java中运行时异常与编译时异常?
WK
|
11月前
|
存储 移动开发 前端开发
HTML5新增了哪些其他元素和属性
这段文字介绍了HTML5中新增的多种元素和属性,包括页面布局元素如header、nav等,表单元素如email、tel输入框等,以及其他元素如canvas、svg等。此外,还介绍了全局及表单属性,例如contenteditable、placeholder等,这些新功能显著增强了HTML5在现代网页设计与开发中的实用性与灵活性。
WK
340 1
|
6月前
|
JSON API 网络架构
HTTP常见的请求方法、响应状态码、接口规范介绍
本文详细介绍了HTTP常见的请求方法、响应状态码和接口规范。通过理解和掌握这些内容,开发者可以更好地设计和实现W
956 83
|
Java C++ 开发者
"深度剖析!接口VS抽象类、聚合VS组合...这6大OOP谜题,你真的全解开了吗?点击揭秘真相!"
【8月更文挑战第19天】接口与聚合是面向对象编程的关键,对于构建灵活、可扩展的软件系统至关重要。本文澄清六个常见疑惑:接口与抽象类的区别、为何使用接口、聚合与组合的不同、接口的新特性、聚合与继承的关系,以及如何合理选择接口、聚合和继承,助你深刻理解并准确应用这些核心概念。
127 0
|
缓存 NoSQL 关系型数据库
数据传输服务的主要功能
【6月更文挑战第4天】数据传输服务的主要功能
293 3
|
前端开发 算法 JavaScript
如何优化前端性能:探索图片压缩与延迟加载技术
本文深入探讨了前端性能优化中的关键问题:图片压缩与延迟加载技术。通过介绍图片压缩的原理和方法,并结合实例说明了如何有效减少图片大小、提升加载速度;同时,详细解析了延迟加载技术的实现原理及其在提高页面加载性能中的作用,为前端开发者提供了实用的优化方案。
|
JSON API 数据格式
使用Python调用API接口获取小红书笔记详情数据
本文将详细介绍如何使用Python编程语言调用小红书API接口,以获取小红书笔记的详情数据。我们将从以下几个方面展开讨论:1) API接口简介;2) Python环境准备;3) API密钥获取;4) 使用Requests库发送API请求;5) 解析响应数据;6) 异常处理与错误排查。