【优选算法篇】分治乾坤,万物归一:在重组中窥见无声的秩序

文章目录

  • 分治专题(二):归并排序的核心思想与进阶应用
    • 前言
    • 第二章:归并排序的应用与延展
      • 2.1 归并排序(medium)
        • 解法(归并排序)
        • C++ 代码实现
        • 易错点提示
        • 时间复杂度和空间复杂度
      • 2.2 数组中的逆序对(hard)
        • 解法(利用归并排序的过程 — 分治)
        • 核心步骤与实现细节
        • C++ 代码实现
        • 易错点提示
        • 时间复杂度和空间复杂度
      • 2.3 计算右侧小于当前元素的个数(hard)
        • 解法(利用归并排序的过程 — 分治)
        • 核心步骤
        • C++ 代码实现
        • 易错点提示
        • 时间复杂度和空间复杂度
      • 2.4 翻转对(hard)
        • 解法(归并排序 — 分治)
        • 核心步骤与实现细节
        • C++ 代码实现
        • 易错点提示
        • 时间复杂度和空间复杂度
        • 优化点
    • 写在最后

分治专题(二):归并排序的核心思想与进阶应用

🚀 欢迎讨论:如果您对内容有任何疑问或见解,欢迎在评论区留言。

👍 点赞、收藏与分享:如果觉得这篇文章对您有帮助,请点赞、收藏并分享给更多朋友。

💡 分享给更多人:一起学习分治策略,掌握归并排序的精髓!


前言

上篇:【优选算法篇】化繁为简,见素抱朴:从乱象中重构秩序的艺术

归并排序是经典的分治法应用,其核心在于“分而治之”的思想。通过不断划分,将一个复杂问题逐步拆解成若干规模更小的子问题,以递归方式求解,再将解合并,从而解决初始问题。本文将围绕归并排序的基本原理,结合排序数组的题目,深入剖析归并排序在分治中的实际应用。


第二章:归并排序的应用与延展

2.1 归并排序(medium)

题目链接:912. 排序数组

题目描述

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

示例 1

  • 输入:nums = [5,2,3,1]
  • 输出:[1,2,3,5]

示例 2

  • 输入:nums = [5,1,1,2,0,0]
  • 输出:[0,0,1,1,2,5]

解法(归并排序)

算法思路

归并排序的过程充分体现了“分而治之”的思想,基本步骤分为以下两部分:

  1. :将数组一分为二,递归地继续分割,直到每个子数组的长度为 1,确保所有分块都已排序。

  2. :将两个已排序的子数组合并成一个有序数组,最终返回整个数组的有序结果。

具体步骤

  • 使用中间点将数组分成 [left, mid][mid + 1, right] 两部分。
  • 递归对左右区间进行排序。
  • 在排序好的左右子数组中,使用双指针将较小的元素依次合并到临时数组 tmp 中。
  • 合并完成后,将 tmp 数组的内容拷贝回原数组。

C++ 代码实现
class Solution {vector<int> tmp; // 临时数组用于存储合并结果
public:vector<int> sortArray(vector<int>& nums) {tmp.resize(nums.size());mergeSort(nums, 0, nums.size() - 1);return nums;}// 归并排序void mergeSort(vector<int>& nums, int left, int right) {if (left >= right) return; // 递归终止条件// 1. 分区int mid = (left + right) / 2;mergeSort(nums, left, mid);mergeSort(nums, mid + 1, right);// 2. 合并两个已排序数组int cur1 = left, cur2 = mid + 1, i = 0;while (cur1 <= mid && cur2 <= right) {tmp[i++] = nums[cur1] <= nums[cur2] ? nums[cur1++] : nums[cur2++];}while (cur1 <= mid) tmp[i++] = nums[cur1++]; // 左边剩余部分while (cur2 <= right) tmp[i++] = nums[cur2++]; // 右边剩余部分// 3. 拷贝回原数组for (int j = 0; j < i; ++j) {nums[left + j] = tmp[j];}}
};

易错点提示
  1. 递归终止条件

    • mergeSort 函数中,left >= right 时停止递归,以防止无穷递归导致的栈溢出。
  2. 合并逻辑

    • cur1cur2 分别指向左、右子数组的起始位置,使用 tmp 存储合并结果。确保在所有元素都合并后,将 tmp 拷贝回 nums 中。
  3. 临时数组的使用

    • 临时数组 tmp 存储每一轮合并结果,以确保排序结果被完整保留到下一轮递归。

时间复杂度和空间复杂度
  • 时间复杂度O(n log n)。每轮合并的时间复杂度为 O(n),分区深度为 log n
  • 空间复杂度O(n),临时数组 tmp 占用额外空间。

2.2 数组中的逆序对(hard)

题目链接:剑指 Offer 51. 数组中的逆序对

题目描述

在一个数组中的两个数字,如果前面的一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

示例 1

  • 输入:[7,5,6,4]
  • 输出:5

解法(利用归并排序的过程 — 分治)

算法思路

归并排序求逆序数是经典的方法。在归并排序的合并过程中,我们可以顺便统计出逆序对的数量,这样可以避免暴力统计的 O(n^2) 时间复杂度。

逆序对的产生方式可分为三种情况:

  1. 左数组中的元素逆序。
  2. 右数组中的元素逆序。
  3. 左数组和右数组中的元素形成逆序。

归并排序过程可以分为两个步骤:

  1. :将数组一分为二,不断划分,直到每个子数组长度为1。
  2. :将左右子数组合并成一个有序数组的过程中,统计逆序对的数量。

核心步骤与实现细节
  1. 为什么可以利用归并排序求逆序对?

    因为在归并排序的过程中,我们通过分治的方法将数组拆分成左右两部分。每部分内部的逆序对可以分别在排序的过程中统计。最终在归并左右数组时,可以统计那些横跨左右数组的逆序对,这三者相加即为总的逆序对数。

  2. 核心问题:如何在合并两个有序数组的过程中统计逆序对的数量?

    在合并左右两个已排序的数组时,可以高效统计出横跨两个数组的逆序对数。考虑以下例子:

    假设有两个有序序列 left = [5, 7, 9]right = [4, 5, 8]
    目标是计算在合并的过程中 left 中的元素大于 right 中的元素的情况数量。

  3. 合并并统计逆序对的过程

    定义指针 cur1 遍历 left 数组,cur2 遍历 right 数组。
    定义 ret 记录逆序对的数量,help 数组临时存储排序的结果。

    • 第一轮

      • 比较 left[cur1]right[cur2],如果 left[cur1] > right[cur2],则意味着从 cur1 到末尾的元素都大于 right[cur2](因为 left 是有序的)。我们可以确定逆序对数量并将结果累加到 ret
      • left[cur1] <= right[cur2],则将 left[cur1] 添加到 help 数组中。
    • 处理剩余元素:若一侧数组元素遍历完,剩余元素直接添加到 help 数组即可,不会再产生新的逆序对。


C++ 代码实现
class Solution {int tmp[50010]; // 临时数组
public:int reversePairs(vector<int>& nums) {return mergeSort(nums, 0, nums.size() - 1);}int mergeSort(vector<int>& nums, int left, int right) {if (left >= right) return 0; // 递归终止条件int ret = 0;// 1. 找中间点,将数组分成两部分int mid = (left + right) >> 1;// 2. 左、右部分的逆序对数量ret += mergeSort(nums, left, mid);ret += mergeSort(nums, mid + 1, right);// 3. 合并并统计逆序对数量int cur1 = left, cur2 = mid + 1, i = 0;while (cur1 <= mid && cur2 <= right) {if (nums[cur1] <= nums[cur2]) {tmp[i++] = nums[cur1++]; // 左侧元素较小,无逆序对} else {ret += mid - cur1 + 1; // 右侧元素小,统计逆序对tmp[i++] = nums[cur2++];}}// 4. 处理剩余元素while (cur1 <= mid) tmp[i++] = nums[cur1++];while (cur2 <= right) tmp[i++] = nums[cur2++];// 5. 将 tmp 数组内容拷贝回原数组for (int j = left; j <= right; j++) {nums[j] = tmp[j - left];}return ret;}
};

易错点提示
  1. 递归终止条件

    • left >= right 时,表示已将数组分割到单个元素,递归停止返回0。
  2. 统计逆序对

    • nums[cur1] > nums[cur2] 时,说明 left[cur1] 及后面的所有元素都大于 right[cur2],则这些元素与 right[cur2] 构成逆序对。统计并更新 ret 的值。
  3. 处理剩余元素

    • 若左数组或右数组有剩余,则直接将剩余部分加入到 tmp,因为剩余部分不会形成逆序对。
  4. 拷贝回原数组

    • 最后将 tmp 的排序结果拷贝回 nums,确保在递归的上一级合并时数组依旧有序。

时间复杂度和空间复杂度
  • 时间复杂度O(n log n)。归并排序的分治递归实现使得时间复杂度达到 O(n log n)
  • 空间复杂度O(n),需要额外的数组存储合并结果。

2.3 计算右侧小于当前元素的个数(hard)

题目链接:315. 计算右侧小于当前元素的个数

题目描述

给你一个整数数组 nums ,按要求返回一个新数组 counts
数组 counts 有如下性质:counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。

示例 1

  • 输入:nums = [5,2,6,1]
  • 输出:[2,1,1,0]

解释

  • 5 的右侧有 2 个更小的元素(2 和 1)。
  • 2 的右侧有 1 个更小的元素(1)。
  • 6 的右侧有 1 个更小的元素(1)。
  • 1 的右侧有 0 个更小的元素。

解法(利用归并排序的过程 — 分治)

算法思路

本题和求数组中的逆序对非常类似,但与逆序对的统计不同之处在于:

  • 需要返回一个数组 counts,记录每个元素右侧更小的元素数量,而不是单一的逆序对总数。
  • 归并排序过程中,除了排序,还需要记录排序过程中元素的索引位置的变化。

核心步骤
  1. 辅助数组和索引绑定

    • 定义一个 index 数组,用于记录元素对应的原始索引,确保元素与下标绑定在一起。
    • ret 数组存储每个元素右侧更小元素的数量。
  2. 递归排序

    • 递归地对数组进行分治排序,并统计左右子数组中每个元素右侧更小的元素数量。
  3. 合并排序并统计逆序对

    • 当合并两个有序数组时,如果发现左侧的某个元素大于右侧的当前元素,则说明该左侧元素右侧的所有元素都小于它。将这些逆序对数量累加到对应的 ret 索引上。
    • 同时,完成左右子数组的归并操作。

C++ 代码实现
class Solution {vector<int> ret;        // 结果数组vector<int> index;      // 记录元素的原始下标int tmpNums[100010];    // 临时数组用于排序int tmpIndex[100010];   // 临时数组用于记录索引排序public:vector<int> countSmaller(vector<int>& nums) {int n = nums.size();ret.resize(n, 0);       // 初始化结果数组为0index.resize(n);        // 初始化下标数组for (int i = 0; i < n; i++) {index[i] = i;       // 初始时,索引与数组位置一一对应}mergeSort(nums, 0, n - 1);return ret;}void mergeSort(vector<int>& nums, int left, int right) {if (left >= right) return;// 1. 分区int mid = (left + right) / 2;// 2. 递归处理左右子区间mergeSort(nums, left, mid);mergeSort(nums, mid + 1, right);// 3. 合并并统计逆序对int cur1 = left, cur2 = mid + 1, i = 0;while (cur1 <= mid && cur2 <= right) {if (nums[cur1] <= nums[cur2]) {tmpNums[i] = nums[cur2];tmpIndex[i++] = index[cur2++];} else {// 当前左侧元素大于右侧元素,统计逆序对ret[index[cur1]] += right - cur2 + 1;tmpNums[i] = nums[cur1];tmpIndex[i++] = index[cur1++];}}// 处理剩余元素while (cur1 <= mid) {tmpNums[i] = nums[cur1];tmpIndex[i++] = index[cur1++];}while (cur2 <= right) {tmpNums[i] = nums[cur2];tmpIndex[i++] = index[cur2++];}// 拷贝回原数组for (int j = left; j <= right; j++) {nums[j] = tmpNums[j - left];index[j] = tmpIndex[j - left];}}
};

易错点提示
  1. 确保索引正确绑定

    • 在每次合并的过程中,索引数组 index 也需要同步排序,以保证结果数组 ret 的统计准确。
  2. 统计逆序对的逻辑

    • nums[cur1] > nums[cur2] 时,说明从 cur2right 的所有元素都小于 nums[cur1],需要将这些数量累加到 ret[index[cur1]]
  3. 递归终止条件

    • left >= right 时停止递归,避免无效操作。

时间复杂度和空间复杂度
  • 时间复杂度O(n log n)。分治递归的时间复杂度是 O(log n),每次合并的时间复杂度是 O(n)
  • 空间复杂度O(n)。需要额外的临时数组 tmpNumstmpIndex 进行合并排序。

2.4 翻转对(hard)

题目链接:493. 翻转对

题目描述

给定一个数组 nums,如果 i < jnums[i] > 2 * nums[j],我们就将 (i, j) 称作一个重要翻转对。
你需要返回给定数组中的重要翻转对的数量。

示例 1

  • 输入:nums = [1,3,2,3,1]
  • 输出:2

解法(归并排序 — 分治)

算法思路

翻转对的统计与逆序对非常类似,都可以利用 归并排序 的思想,将问题分解为三部分:

  1. 左数组中的翻转对数量。
  2. 右数组中的翻转对数量。
  3. 左右数组合并时的翻转对数量。

由于翻转对要求的是 nums[i] > 2 * nums[j],直接在合并排序时统计会比较困难,因此:

  • 我们在归并排序前,提前统计 左右两部分数组中满足条件的翻转对数量。
  • 在统计完成后,再进行归并排序。

核心步骤与实现细节
  1. 统计翻转对数量

    • 使用两个指针 cur1cur2,分别遍历左、右子数组。
    • 对于每个左数组元素 nums[cur1],找到右数组中第一个不满足 nums[cur1] > 2 * nums[cur2] 的位置 cur2
    • 此时,cur2 - mid - 1 即为当前 cur1 的翻转对数量,累加到结果中。
  2. 合并两个有序数组

    • 合并时,按照归并排序的逻辑,将两个子数组排序,并写入临时数组。
  3. 递归分治

    • 每次划分数组为 [left, mid][mid + 1, right],递归统计翻转对数量并排序。

C++ 代码实现
class Solution {int tmp[50010]; // 临时数组用于合并排序
public:int reversePairs(vector<int>& nums) {return mergeSort(nums, 0, nums.size() - 1);}int mergeSort(vector<int>& nums, int left, int right) {if (left >= right) return 0;int ret = 0;// 1. 分区int mid = (left + right) / 2;// 2. 递归计算左右区间的翻转对数量ret += mergeSort(nums, left, mid);ret += mergeSort(nums, mid + 1, right);// 3. 统计翻转对数量int cur1 = left, cur2 = mid + 1;while (cur1 <= mid) {while (cur2 <= right && nums[cur2] * 2 < nums[cur1]) {cur2++;}ret += cur2 - mid - 1;cur1++;}// 4. 合并两个有序数组cur1 = left, cur2 = mid + 1;int i = left;while (cur1 <= mid && cur2 <= right) {tmp[i++] = nums[cur1] <= nums[cur2] ? nums[cur1++] : nums[cur2++];}while (cur1 <= mid) tmp[i++] = nums[cur1++];while (cur2 <= right) tmp[i++] = nums[cur2++];for (int j = left; j <= right; j++) {nums[j] = tmp[j];}return ret;}
};

易错点提示
  1. 统计翻转对的逻辑

    • 必须确保 cur2 指针只向右移动,不会回退,避免重复计算。
    • 注意翻转对的判断条件 nums[cur1] > 2 * nums[cur2],需要考虑到浮点运算可能导致的精度问题,因此 2 * nums[cur2] 可能需要写成 nums[cur1] > 2LL * nums[cur2]
  2. 归并排序的逻辑

    • 合并时,确保临时数组和原数组的元素同步,避免在递归的上一层出错。
  3. 边界条件

    • 单元素或空数组的递归终止条件是 left >= right

时间复杂度和空间复杂度
  • 时间复杂度O(n log n)

    • 每次递归的深度是 log n,每层递归需要合并排序和统计翻转对,复杂度为 O(n)
  • 空间复杂度O(n)

    • 使用了额外的临时数组 tmp 进行排序。

优化点
  1. 使用更大的临时数组(避免频繁分配内存)。
  2. 在统计翻转对时,提前检查是否有可能的翻转对,减少无意义的遍历。

通过以上方法,翻转对的数量可以在 O(n log n) 的时间复杂度内高效统计。

写在最后

在本次归并排序专题中,我们以经典的分治思想为核心,逐层剖析了归并排序的精髓及其在算法中的高级应用。从数组排序到统计逆序对,再到复杂的翻转对和右侧更小元素计数,归并排序不仅是解决基础问题的利器,更是攻克高阶难题的关键。我们以逐步深入的方式,从基础实现到优化分析,贯穿了分治思想的深度与广度。

分治法的核心在于“分而治之”,通过不断将大问题拆解为小问题,并利用递归与合并的方式重新组合结果。在归并排序中,借助临时数组和指针操作,我们能够高效完成排序,并在此过程中完成复杂的统计任务。它不仅展现了算法的美学,更体现了计算机科学中化繁为简的哲学。

通过归并排序的深入学习,我们不仅掌握了分治策略的实现,更体验了算法优化的艺术。期待这篇文章能为读者打开分治法的大门,让你在算法学习中游刃有余!


以上就是关于【优选算法篇】分治乾坤,万物归一:在重组中窥见无声的秩序的内容啦,各位大佬有什么问题欢迎在评论区指正,或者私信我也是可以的啦,您的支持是我创作的最大动力!❤️

在这里插入图片描述

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

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

相关文章

【微软:多模态基础模型】(3)视觉生成

欢迎关注【youcans的AGI学习笔记】原创作品 【微软&#xff1a;多模态基础模型】&#xff08;1&#xff09;从专家到通用助手 【微软&#xff1a;多模态基础模型】&#xff08;2&#xff09;视觉理解 【微软&#xff1a;多模态基础模型】&#xff08;3&#xff09;视觉生成 【微…

netcore Kafka

一、新建项目KafakDemo <ItemGroup><PackageReference Include"Confluent.Kafka" Version"2.6.0" /></ItemGroup> 二、Program.cs using Confluent.Kafka; using System; using System.Threading; using System.Threading.Tasks;names…

工业生产安全-安全帽第一篇-opencv及java开发环境搭建

一.背景 公司是非煤采矿业&#xff0c;核心业务是采选&#xff0c;大型设备多&#xff0c;安全风险因素多。当下政府重视安全&#xff0c;头部技术企业的安全解决方案先进但价格不低&#xff0c;作为民营企业对安全投入的成本很敏感。利用我本身所学&#xff0c;准备搭建公司的…

fastadmin多个表crud连表操作步骤

1、crud命令 php think crud -t xq_user_credential -u 1 -c credential -i voucher_type,nickname,user_id,voucher_url,status,time --forcetrue2、修改控制器controller文件 <?phpnamespace app\admin\controller;use app\common\controller\Backend;/*** 凭证信息…

【英特尔IA-32架构软件开发者开发手册第3卷:系统编程指南】2001年版翻译,2-26

文件下载与邀请翻译者 学习英特尔开发手册&#xff0c;最好手里这个手册文件。原版是PDF文件。点击下方链接了解下载方法。 讲解下载英特尔开发手册的文章 翻译英特尔开发手册&#xff0c;会是一件耗时费力的工作。如果有愿意和我一起来做这件事的&#xff0c;那么&#xff…

Essential Cell Biology--Fifth Edition--Chapter one (8)

1.1.4.6 The Cytoskeleton [细胞骨架] Is Responsible for Directed Cell Movements 细胞质基液不仅仅是一种无结构的化学物质和细胞器的混合物[soup]。在电子显微镜下&#xff0c;我们可以看到真核细胞的细胞质基液是由长而细的丝交叉而成的。通常[Frequently]&#xff0c;可…

RK3568 Linux 系统加系统运行指示灯

一、dts配置 gpio-leds {status = "okay";compatible = "gpio-leds";work-led {gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>

C++11(六)----包装器function和bind

文章目录 包装器&#xff1a;function包装器&#xff1a;bind 包装器&#xff1a;function function接口介绍 在头文件<functional>中 语法&#xff1a;function的语法比较特殊 function<返回值(参数)> 自定义变量名 要被包装的可调用对象 class Plus { public:…

店铺推推-项目测试用例设计(Xmind)

项目介绍&#xff1a; 技术栈: Spring BootMyBatisRedis项目描述&#xff1a; 项目旨在为消费者提供一个公平、公开、透明的平台&#xff0c;让消费者能够基于真实的消费体验对店铺进行评价和 推荐&#xff0c;并为其他潜在消费者提供参考。同时&#xff0c;店铺推推也是为商家…

c++--------《set 和 map》

c--------《set 和 map》 1 set系列的使⽤1.1 set类的介绍1.2 set的构造和迭代器1.3 set重要接口 2 实现样例2.1: insert和迭代器遍历使⽤样例&#xff1a;2.2: find和erase使⽤样例&#xff1a; 练习3.map系列的使用3.1 map类的介绍3.1.1 pair类型介绍 3.2 map的数据修改3.3mu…

GIS融合之路(八)-如何用Cesium直接加载OSGB文件(不用转换成3dtiles)

系列传送门&#xff1a; 山海鲸可视化&#xff1a;GIS融合之路&#xff08;一&#xff09;技术选型CesiumJS/loaders.gl/iTowns? 山海鲸可视化&#xff1a;GIS融合之路&#xff08;二&#xff09;CesiumJS和ThreeJS深度缓冲区整合 山海鲸可视化&#xff1a;GIS融合之路&…

QQ 小程序已发布,但无法被搜索的解决方案

前言 我的 QQ 小程序在 2024 年 8 月就已经审核通过&#xff0c;上架后却一直无法被搜索到。打开后&#xff0c;再在 QQ 上下拉查看 “最近使用”&#xff0c;发现他出现一下又马上消失。 上线是按正常流程走的&#xff0c;开发、备案、审核&#xff0c;没有任何违规&#xf…

word 中长公式换行 / 对齐 | Mathtype 中长公式换行拆分 | latex 中长公式换行

注&#xff1a;本文为 “word 中长公式换行 / 对齐 | Mathtype 中长公式换行拆分 | latex 中长公式换行” 相关专题文章合辑。 未整理去重。 “公式较长时最好在等号 “&#xff1d;” 处转行&#xff0c;如难实现&#xff0c;则可在&#xff0b;、&#xff0d;、、 运算符号处…

【优选算法 — 滑动窗口】串联所有单词的子串 最小覆盖子串

串联所有单词的子串 串联所有单词的子串 题目描述 题目解析 算法原理 以示例一为例&#xff0c;一定要记得&#xff0c;words中的每一个字符串长度相同&#xff0c;所以我们可以根据 words 中的每一个字符串的长度length&#xff0c;将 s 这个字符串以 length 个为一组来…

WEB攻防-通用漏洞SQL注入sqlmapOracleMongodbDB2等

SQL注入课程体系&#xff1a; 1、数据库注入-access mysql mssql oracle mongodb postgresql 2、数据类型注入-数字型 字符型 搜索型 加密型&#xff08;base64 json等&#xff09; 3、提交方式注入-get post cookie http头等 4、查询方式注入-查询 增加 删除 更新 堆叠等 …

7.揭秘C语言输入输出内幕:printf与scanf的深度剖析

揭秘C语言输入输出内幕&#xff1a;printf与scanf的深度剖析 C语言往期系列文章目录 往期回顾&#xff1a; VS 2022 社区版C语言的安装教程&#xff0c;不要再卡在下载0B/s啦C语言入门&#xff1a;解锁基础概念&#xff0c;动手实现首个C程序C语言概念之旅&#xff1a;解锁关…

SHELL(4)脚本与用户交互以及if条件判断

声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&a…

Springboot集成ElasticSearch实现minio文件内容全文检索

一、docker安装Elasticsearch &#xff08;1&#xff09;springboot和Elasticsearch的版本对应关系如下&#xff0c;请看版本对应&#xff1a; 注意安装对应版本&#xff0c;否则可能会出现一些未知的错误。 &#xff08;2&#xff09;拉取镜像 docker pull elasticsearch:7…

使用chrome 访问虚拟机Apache2 的默认页面,出现了ERR_ADDRESS_UNREACHABLE这个鸟问题

本地环境 主机MacOs Sequoia 15.1虚拟机Parallels Desktop 20 for Mac Pro Edition 版本 20.0.1 (55659)虚拟机-操作系统Ubuntu 22.04 服务器版本 最小安装 开发环境 编辑器编译器调试工具数据库http服务web开发防火墙Vim9Gcc13Gdb14Mysql8Apache2Php8.3Iptables 第一坑 数…

定时器的小应用

第一个项目 第一步&#xff0c;RCC开启时钟&#xff0c;这个基本上每个代码都是第一步&#xff0c;不用多想&#xff0c;在这里打开时钟后&#xff0c;定时器的基准时钟和整个外设的工作时钟就都会同时打开了 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);第二步&…