算法专题(八):分治-归并排序
目录
一、排序数组
1.1 题目
2.2 思路
2.3 代码实现
二、LCR 170. 交易逆序对的总数 (数组中的逆序对)
2.1 题目
2.2 思路
方法一:快速统计出某个数前面有多少个数比它大
方法二:快速统计出某个数后面有多少个数比它小
2.3 代码实现
编辑 三、计算右侧小于当前元素的个数
3.1 题目
3.2 思路
3.3 代码实现
四、翻转对
4.1 题目
4.2 思路
4.3 代码实现
算法专题:uyeonashi的博客-CSDN博客
一、排序数组
1.1 题目
2.2 思路
归并排序的流程充分的体现了「分而治之」的思想,大体过程分为两步:
◦ 分:将数组一分为二为两部分,一直分解到数组的长度为 1 ,使整个数组的排序过程被分为
「左半部分排序」 + 「右半部分排序」;
◦ 治:将两个较短的「有序数组合并成一个长的有序数组」,一直合并到最初的长度。
2.3 代码实现
class Solution {
public:vector<int> tmp; // 辅助数组void mergeSort(vector<int>& nums,int left,int right){if(left >= right) return;// 1. 选择中间点划分区域int mid = (left+right) >> 1;//[left,mid] [mid+1,right]// 2. 把左右区间排序mergeSort(nums,left,mid);mergeSort(nums,mid+1,right);//3. 合并两个有序数组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++];//将辅助数组中的值放到原数组中for(i = left; i<= right; i++)nums[i] = tmp[i-left];}vector<int> sortArray(vector<int>& nums) {tmp.resize(nums.size());mergeSort(nums,0,nums.size()-1);return nums;}
};
二、LCR 170. 交易逆序对的总数 (数组中的逆序对)
2.1 题目
2.2 思路
用归并排序求逆序数是很经典的方法,主要就是在归并排序的合并过程中统计出逆序对的数量,也就是在合并两个有序序列的过程中,能够快速求出逆序对的数量。
我们将这个问题分解成几个小问题,逐一破解这道题。
注意:默认都是升序,如果掌握升序的话,降序的归并过程也是可以解决问题的。
• 先解决第一个问题,为什么可以利用归并排序?
如果我们将数组从中间划分成两个部分,那么我们可以将逆序对产生的方式划分成三组:
- 逆序对中两个元素:全部从左数组中选择
- 逆序对中两个元素:全部从右数组中选择
- 逆序对中两个元素:一个选左数组另一个选右数组
根据排列组合的分类相加原理,三种种情况下产生的逆序对的总和,正好等于总的逆序对数量。
而这个思路正好匹配归并排序的过程:
- 先排序左数组;
- 再排序右数组;
- 左数组和右数组合二为一
因此,我们可以利用归并排序的过程,先求出左半数组中逆序对的数量,再求出右半数组中逆序对的数量,最后求出一个选择左边,另一个选择右边情况下逆序对的数量,三者相加即可。
• 解决第二个问题,为什么要这么做?
在归并排序合并的过程中,我们得到的是两个有序的数组。我们是可以利用数组的有序性,快速统计出逆序对的数量,而不是将所有情况都枚举出来。
• 最核心的问题,如何在合并两个有序数组的过程中,统计出逆序对的数量?
合并两个有序序列时求逆序对的方法有两种:
- 快速统计出某个数前面有多少个数比它大;
- 快速统计出某个数后面有多少个数比它小;
方法一:快速统计出某个数前面有多少个数比它大
通过一个示例来演示方法一:
假定已经有两个已经有序的序列以及辅助数组 left = [5, 7, 9] right = [4, 5, 8] help = [ ],通过合并两个有序数组的过程,来求得逆序对的数量:
规定如下定义来叙述过程:
cur1 遍历 left 数组,cur2 遍历 right 数组
ret 记录逆序对的数量
第一轮循环:
left[cur1] > right[cur2],由于两个数组都是升序的,那么我们可以断定,此刻 left 数组中[cur1, 2] 区间内的 3 个元素均可与 right[cur2] 的元素构成逆序对,因此可以累加逆序对的数量 ret+= 3,并且将 right[cur2] 加入到辅助数组中,cur2++ 遍历下一个元素。
第一轮循环结束后:left = [5, 7, 9] right = [x, 5, 8] help = [4] ret = 3 cur1 = 0 cur2 = 1
第二轮循环:
left[cur1] == right[cur2],由于两个数组都是升序,这个时候对于元素 left[cur1] 来说,我们已经可以断定 right 数组中 [0, cur2) 左闭右开区间上的元素都是比它小的。因此此时可以统计逆序对的数量 ret += cur2 - 0,并且将 left[cur1] 放入到辅助数组中去,cur1++ 遍历下一个元素。
第二轮循环结束后:left = [x, 7, 9] right = [x, 5, 8] help = [4, 5] ret = 1 cur1 = 1 cur2 = 1
第三轮循环:
left[cur1] > right[cur2],与第一轮循环相同,此刻 left 数组中[cur1, 2] 区间内的 2 个元素均可与 right[cur2] 的元素构成逆序对,更新 ret 的值为 ret += 2,并且将 right[cur2] 加入到辅助数组中去,cur2++ 遍历下一个元素。
第三轮循环结束后:left = [x, 7, 9] right = [x, x, 8] help = [4, 5, 5] ret = 5 cur1 = 1 cur2 = 2
第四轮循环:
left[cur1] < right[cur2],由于两个数组都是升序的,因此我们可以确定 left[cur1] 比 right 数组中的所有元素都要小。left[cur1] 这个元素是不可能与 right 数组中的元素构成逆序对。因此,大胆的将 left[cur1] 这个元素加入到辅助数组中去,不更细 ret 的值。
第四轮循环结束后:left = [x, x, 9] right = [x, x, 8] help = [4, 5, 5, 7] ret = 5 cur1 = 2 cur2 = 2
第五轮循环:
left[cur1] > right[cur2],与第一、第三轮循环相同。此时 left 数组内的 1 个元素能与right[cur2] 构成逆序对,更新 ret 的值,并且将 right[cur2] 加入到辅助数组中去。
第五轮循环结束后:left = [x, x, 9] right = [x, x, x] help = [4, 5, 5, 7, 8] ret = 6 cur1 = 2 cur2 = 2
处理剩余元素:
• 如果是左边出现剩余,说明左边剩下的所有元素都是比右边元素大的,但是它们都是已经被计算过的(我们以右边的元素为基准的),因此不会产生逆序对,仅需归并排序即可。
• 如果是右边出现剩余,说明右边剩下的元素都是比左边大的,不符合逆序对的定义,因此也不需要处理,仅需归并排序即可。
整个过程只需将两个数组遍历一遍即可,时间复杂度为 O(N)。
由上述过程我们可以得出方法一统计逆序对的关键点:
在合并有序数组的时候,遇到左数组当前元素 > 右数组当前元素时,我们可以通过计算左数组中剩余元素的长度,就可快速求出右数组当前元素前面有多少个数比它大,对比暴力解法中一个一个枚举逆序对效率快了许多。
方法二:快速统计出某个数后面有多少个数比它小
2.3 代码实现
这里只写升序版本的代码,感兴趣的话可以自己尝试下降序版本的代码
class Solution {
public:int tmp[50010];int mergeSort(vector<int>& nums,int left,int right){if(left >= right) return 0;int ret = 0;// 1. 找中间点将数组分成两部分int mid = (left+right) >> 1;//[left,mid] [mid+1,right]// 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++];}}// 处理一下排序while(cur1 <= mid) tmp[i++] = nums[cur1++];while(cur2 <= right) tmp[i++] = nums[cur2++];//将辅助数组中的值放到nums中for( i = left; i <= right;i++)nums[i] = tmp[i-left];return ret;}int reversePairs(vector<int>& nums) {return mergeSort(nums,0,nums.size()-1);}
};
三、计算右侧小于当前元素的个数
3.1 题目
3.2 思路
这一道题的解法与 求数组中的逆序对 的解法是类似的,但是这一道题要求的不是求总的个数,而
是要返回一个数组,记录每一个元素的右边有多少个元素比自己小。
但是在我们归并排序的过程中,元素的下标是会跟着变化的,因此我们需要一个辅助数组,来将数组元素和对应的下标绑定在一起归并,也就是再归并元素的时候,顺势将下标也转移到对应的位置上。
由于我们要快速统计出某一个元素后面有多少个比它小的,因此我们可以利用求逆序对的第二种方法。
算法流程:
• 创建两个全局的数组:
vector<int> index:记录下标
vector<int> ret:记录结果
index 用来与原数组中对应位置的元素绑定,ret 用来记录每个位置统计出来的逆序对的个数。
• countSmaller() 主函数:
a. 计算 nums 数组的大小为 n;
b. 初始化定义的两个全局的数组;
i. 为两个数组开辟大小为 n 的空间
ii. index 初始化为数组下标;
iii. ret 初始化为 0
c. 调用 mergeSort() 函数,并且返回 ret 结果数组。
• void mergeSort( vector<int>& nums, int left, int right ) 函数:
函数设计:通过修改全局的数组 ret, 统计出每一个位置对应的逆序对的数量,并且排序;
无需返回值,因为直接对全局变量修改,当函数结束的时候,全局变量已经被修改成最后的结果。
• mergeSort() 函数流程:
a. 定义递归出口:left >= right 时,直接返回;
b. 划分区间:根据中点 mid,将区间划分为 [left, mid] 和 [mid + 1, right];
c. 统计左右两个区间逆序对的数量:
i. 统计左边区间 [left, mid] 中每个元素对应的逆序对的数量到 ret 数组中,并排序;
ii. 统计右边区间 [mid + 1, right] 中每个元素对应的逆序对的数量到 ret 数组中,并排序。
d. 合并左右两个有序区间,并且统计出逆序对的数量:
i. 创建两个大小为 right - left + 1 大小的辅助数组:
• numsTmp: 排序用的辅助数组;
• indexTmp:处理下标用的辅助数组。
ii. 初始化遍历数组的指针:cur1 = left(遍历左半部分数组)cur2 = mid + 1(遍历右半边数组)dest = 0(遍历辅助数组)curRet(记录合并时产生的逆序对的数量);
iii. 循环合并区间:
• 当 nums[cur1] <= nums[cur2] 时:
◦ 说明此时 [mid + 1, cur2) 之间的元素都是小于 nums[cur1] 的,需要累加到 ret 数组的 indext[cur1] 位置上(因为 index 存储的是元素对应位置在原数组中的下标)
◦ 归并排序:不仅要将数据放在对应的位置上,也要将数据对应的坐标也放在对应的位置上,使数据与原始的下标绑定在一起移动。
• 当 nums[cur1] > nums[cur2] 时,无需统计,直接归并,注意 index 也要跟着归并。
iv. 处理归并排序中剩余的元素;
• 当左边有剩余的时候,还需要统计逆序对的数量;
• 当右边还有剩余的时候,无需统计,直接归并。
v. 将辅助数组的内容替换到原数组中去;
3.3 代码实现
class Solution {
public:vector<int> ret;vector<int> index; //记录nums中的原始下标int tmpNums[500010];int tmpIndex[500010];void mergeSort(vector<int>& nums,int left,int right){if(left >= right) return;// 根据中间元素划分区域int mid = (left+right) >> 1;// [left,mid] [mid+1,right]//先处理左右两部分mergeSort(nums,left,mid);mergeSort(nums,mid+1,right);// 处理一左一右的情况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];i++; cur2++;}else{ret[index[cur1]] += right-cur2+1;tmpNums[i] = nums[cur1];tmpIndex[i] = index[cur1];i++; cur1++;}}//处理剩下的while(cur1 <= mid) {tmpNums[i] = nums[cur1];tmpIndex[i] = index[cur1];i++; cur1++;}while(cur2 <= right){tmpNums[i] = nums[cur2];tmpIndex[i] = index[cur2];i++; cur2++;}for(int j = left; j <= right; j++){nums[j] = tmpNums[j-left];index[j] = tmpIndex[j-left];}}vector<int> countSmaller(vector<int>& nums) {ret.resize(nums.size());//初始化一下index数组index.resize(nums.size());for(int i = 0; i < nums.size(); i++)index[i] = i;mergeSort(nums,0,nums.size()-1); return ret;}
};
四、翻转对
4.1 题目
4.2 思路
翻转对和逆序对的定义大同小异,逆序对是前面的数要大于后面的数。而翻转对是前面的一个数要大于后面某个数的两倍。因此,我们依旧可以用归并排序的思想来解决这个问题。
算法思路:
大思路与求逆序对的思路一样,就是利用归并排序的思想,将求整个数组的翻转对的数量,转换成三部分:左半区间翻转对的数量,右半区间翻转对的数量,一左一右选择时翻转对的数量。重点就是在合并区间过程中,如何计算出翻转对的数量。
与上个问题不同的是,上一道题我们可以一边合并一遍计算,但是这道题要求的是左边元素大于右边元素的两倍,如果我们直接合并的话,是无法快速计算出翻转对的数量的。
例如 left = [4, 5, 6] right = [3, 4, 5] 时,如果是归并排序的话,我们需要计算 left 数组中有多少个能与 3 组成翻转对。但是我们要遍历到最后一个元素 6 才能确定,时间复杂度较高。
因此我们需要在归并排序之前完成翻转对的统计。
下面依旧以一个示例来模仿两个有序序列如何快速求出翻转对的过程:
假定已经有两个已经有序的序列 left = [4, 5, 6] right = [1, 2, 3] 。
用两个指针 cur1 cur2 遍历两个数组。
◦ 对于任意给定的 left[cur1] 而言,我们不断地向右移动 cur2,直到 left[cur1] <= 2 *right[cur2]。此时对于 right 数组而言,cur2 之前的元素全部都可以与 left[cur1] 构成翻转对。
◦ 随后,我们再将 cur1 向右移动一个单位,此时 cur2 指针并不需要回退(因为 left 数组是升序的)依旧往右移动直到 left[cur1] <= 2 * right[cur2]。不断重复这样的过程,就能够求出所有左右端点分别位于两个子数组的翻转对数目。
由于两个指针最后都是不回退的的扫描到数组的结尾,因此两个有序序列求出翻转对的时间复杂度是 O(N)。
综上所述,我们可以利用归并排序的过程,将求一个数组的翻转对转换成求 左数组的翻转对数量 +右数组中翻转对的数量 + 左右数组合并时翻转对的数量。
4.3 代码实现
class Solution {
public:int tmp[50010];int mergeSort(vector<int>& nums,int left,int right){if(left >= right) return 0;int ret = 0;// 先根据中间元素划分区间int mid = (left + right) >> 1;// [left,mid] [mid+1,right]// 先算出两侧的翻转对ret += mergeSort(nums,left,mid);ret += mergeSort(nums,mid+1,right);// 计算翻转对的数量int cur1 = left, cur2 = mid+1, i = 0;while(cur1 <= mid && cur2 <= right){while(cur2 <= right && nums[cur2] >= nums[cur1]/2.0 ) cur2++;if(cur2 > right) break;ret += right-cur2+1;cur1++;} // 合并两个有序数组cur1 = left,cur2 = mid+1;while(cur1 <= mid && cur2 <= right)tmp[i++] = nums[cur1] <= nums[cur2] ? nums[cur2++] : nums[cur1++];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-left];return ret; }int reversePairs(vector<int>& nums) {return mergeSort(nums,0,nums.size()-1);}
};
本篇完,下篇见!
相关文章:
算法专题(八):分治-归并排序
目录 一、排序数组 1.1 题目 2.2 思路 2.3 代码实现 二、LCR 170. 交易逆序对的总数 (数组中的逆序对) 2.1 题目 2.2 思路 方法一:快速统计出某个数前面有多少个数比它大 方法二:快速统计出某个数后面有多少个数比它小 …...
51单片机使用定时器实现LCD1602的时间显示(STC89C52RC)
本文前半部分直接给出实现(注意进位问题是秒->分->小时,用 if 嵌套即可实现),后半部分讲解定时器和中断系统。 效果展示: LCD1602电路图: 项目结构: 代码实现: main.c #…...
微软2025年AI技术深度解析:从多模态大模型到企业级代理服务
微软2025年AI技术深度解析:从多模态大模型到企业级代理服务 一、微软AI技术全景概览 在2025年的AI领域,微软通过Azure AI Foundry、多模态大模型、企业级AI代理三大核心技术,构建了覆盖开发、部署、应用全流程的AI生态体系。根据最新财报数…...
24 设计模式总结
设计模式分类(意图) • 创建型模式:创建对象的机制,从所需要实例化的对象中解耦。 • 结构型模式:将对象或类组装到更大的结构中。 • 行为型模式:负责对象间的交互和分配职责。分类的目的是为了更抽象的了…...
【ARTS】2873.有序三元组中的最大值!
前言 仅做学习使用,侵删 什么是ARTS? 算法(Algorithm): 每周至少一道LeetCode算法题,加强编程训练和算法学习 阅读(Review): 阅读并点评至少一篇英文技术文章,提高英文水平 技巧 (Tip):学习至少一个技…...
Mysql进阶
目录 一.Mysql架构 1.连接层 2.服务层 3.引擎层 4.物理文件存储层 二.Mysql引擎 1.InnoDB 2.MyISAM 三.索引 1.什么是索引 2.为什么要有索引 3.索引的原理 4.索引优势 5.索引劣势 6.索引分类 主键索引 唯一索引 单值索引 组合索引(复合索引&#…...
探秘JVM内部
在我们编写Java代码,点击运行后,会发生什么事呢? 首先,Java源代码会经过Java编译器将其编译成字节码,放在.class文件中 然后这些字节码文件就会被加载到jvm中,然后jvm会读取这些文件,调用相关…...
c语言学习12天
c语言的宏定义:宏定义单纯的文本替换不会检查语法是否合法 #include #pragma 以及开头的#都属于预处理指令 预处理指令:在gcc编译套件中的cpp预处理器对程序进行编译之前所做的一些动作,如#include预处理指令就是在程序编译之前有预处理器…...
公司内网部署离线deepseek本地模型实战
企业内部可能有些数据比较敏感,不能连接互联网。deepseek来提高工作效率,这个时候你可以利用ollama在内网本地部署来实现。 本式样是先在自己电脑上用虚拟机部署好,再用U盘把虚拟机文件复制到内网去。 一、使用VMware新建WIN2022虚拟机 &a…...
rocketmq中的延迟队列使用详解
RocketMQ的延迟队列通过预设的延迟等级实现消息的定时投递,适用于订单超时、定时通知等高并发场景。以下是其核心原理、使用方式及优化策略的详细解析: 一、实现原理 延迟等级机制 RocketMQ默认提供18个固定延迟等级(1s、5s、10s、30s、1m、2…...
VB.NET Asp.Net Core模板WebAPI应用-宝塔面板Linux系统通过Docker部署
宝塔面板支持在Linux系统上部署Docker容器吗? 如何在宝塔面板上通过Docker部署VB.NET应用? Docker容器中的VB.NET Asp.Net Core WebAPI应用如何配置? 一,首先,创建一个ASP.NET Core测试项目 1.1 打开VS2019/2022,创建一个.NTE6 Core控制台应…...
4985 蜗牛
4985 蜗牛 ⭐️难度:中等 ⭐️考点:2023、省赛、动态规划 📖 📚 import java.util.Scanner; // 1:无需package // 2: 类名必须Main, 不可修改public class Main {public static void main(String[] args) {Scanner sc new Sc…...
springboot多模块工程打包部署运行
1、问题概述? 基于实际项目打包过程,各种配置面面俱到,已配置的可跳过。 本文以打包jar包为模板进行操作,部署方便。 在实际的开发中,项目的模块可能较多,如果都放在一个项目的目录中,势必会造成项目包中的文件冗余,难以管理,这个时候就需要使用多模块管理项目。 …...
吴恩达深度学习复盘(8)神经网络中激活函数的建模
激活函数的建模原理 到目前为止,在隐藏层等一直使用激活函数,最初通过逻辑回归建立新网络,组合多个逻辑回归单元。这表明激活函数在神经网络构建中一直存在,且最初的网络构建方式与逻辑回归相关。实际上,激活函数的种类…...
1-linux的基础知识
一.linux的文件系统结构 windows文件系统 微软windows系统将硬盘上的几个分区,用A: B: C: D:等符号标识。存取文件时一定要清楚放在那个磁盘的那个目录下。 linux文件系统 linux文件系统的组织模式犹如一颗倒置的树,这与windows文件系统有很大的差别…...
docker 常用命令
文章目录 一、帮助启动类命令启动docker停止docker重启docker查看docker状态开机自启查看docker概要信息 二、镜像命令列出本地主机上的镜像搜索镜像拉取镜像查看镜像所占空间删除镜像 三、容器命令新建运行容器交互式启动容器守护进程式启动容器列出当前所有的容器进入容器之后…...
使用docker搭建redis镜像时云服务器无法访问到国外的docker官网时如何解决
下载redis镜像 docker redis:版本号 此时截图中无法访问到国外的docker官网 解决方案: 通过更换镜像源来正常下载redis镜像 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<EOF {"registry-mirrors": ["https://docker.1…...
基于Python的人脸识别校园考勤系统
【Python】基于Python的人脸识别校园考勤系统 (完整系统源码开发笔记详细部署教程)✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 🌟 该系统主要分为前端和后端两个部分,前端👀负责人脸采集、人…...
微信小程序学习实录11:startLocationUpdateBackground:fail auth deny
startLocationUpdateBackground:fail auth deny 表明小程序在尝试开启后台位置更新时,用户授权被拒绝。以下是可能的原因及解决方法: 原因分析 缺少必要的用户授权: 使用 wx.startLocationUpdateBackground 接口需要用户授予 scope.userLo…...
DAPP实战篇:规划下我们的开发线路
前言 在DApp实战篇:先用前端起个项目一文中我们起了一个前端项目,在后续开发中笔者将带领大家一步步完成这个DAPP,为了方便后续讲解,本篇将完整说明后续我们要进行的开发和思路。 主打前端 实际上一个完整的DAPP是由前端和智能…...
docker配置redis容器时配置文件docker-compose.yml示例
1.配置数据节点(主从节点) version: 3.7 services:master:image: redis:5.0.9container_name: redis-masterrestart: alwayscommand: redis-server --appendonly yesports:- 6379:6379slave1:image: redis:5.0.9container_name: redis-slave1restart: a…...
清晰易懂的 Jenkins 安装与核心使用教程
Jenkins 是业界领先的开源自动化服务器,用于实现持续集成与持续交付(CI/CD)。本教程将覆盖 安装部署、核心功能配置、避坑指南,助你快速掌握企业级自动化流水线搭建! 一、Jenkins 安装(全平台指南ÿ…...
anomalib—2—输入图像大小调整
三个地方 第一:在定义model时,要在pre_processor里面去定义一个前处理,前处理就一个功能,定义图像的大小 pre_processor0 Patchcore.configure_pre_processor( image_size (128, 128)) model Patchcore( backbone"wide_r…...
小型园区组网图
1. 在小型园区中,S5735-L-V2通常部署在网络的接入层,S8700-4通常部署在网络的核心,出口路由器一般选用AR系列路由器。 2. 接入交换机与核心交换机通过Eth-Trunk组网保证可靠性。 3. 每个部门业务划分到一个VLAN中,部门间的业务在C…...
编程哲学——TCP可靠传输
TCP TCP可靠传输 TCP的可靠传输表现在 (1)建立连接时三次握手,四次挥手 有点像是这样对话: ”我们开始对话吧“ ”收到“ ”好的,我收到你收到了“ (2)数据传输时ACK应答和超时重传 ”我们去吃…...
2024华为OD机试真题-任务最优调度(C++/Java/Python)-E卷-200分
2024华为OD机试最新E卷题库-(D卷+E卷)-(JAVA、Python、C++) 目录 题目描述 输入描述 输出描述 用例1 考点 题目解析 代码 c++ java python 题目描述 给定一个正整数数组表示待系统执行的任务列表,数组的每一个元素代表一个任务,元素的值表示该任务的类型。请计算执…...
蓝桥杯 2023省B 飞机降落 dfs
传送门 P9241 [蓝桥杯 2023 省 B] 飞机降落 - 洛谷 n<10,考虑dfs,只有当 当前飞机的到达时刻盘旋时间 < 上一个飞机降落的时刻 时,当前飞机才能降落 const int N 1e3 10;int n; struct Node {LL t,d,l; }a[N];bool st[N];bool dfs(in…...
Mybatis--动态SQL
动态SQL是MyBatis的重要特征之一,能够完成不同条件下的SQL拼接,参考文档:动态 SQL_MyBatis中文网 一、<if>标签 该标签主要适用的情况为实现必填字段和非必填字段: 例如下面的例子就是将用户表中的性别设置成了非必填字段…...
计算机视觉中的基于网格的卷绕算法全解析
大家好呀~今天给大家带来一个超级实用且有趣的计算机视觉技巧:基于网格的卷绕算法(Grid Warp Algorithm)!如果你对图像变形、动画制作感兴趣,那一定不要错过这篇文章哦!话不多说,直接…...
xv6 文件系统
Buffer Cache buffer Cache 结构体 bcache 存放了 NBUF 个 buf 框,每个框对应 disk 上某一个 block。从初始化函数 binit中可以看出,bcache 是一个循环双向链表。通过双链表组织这些 buf,以近似 LRU 的策略管理,大概如下图。 st…...
Python Cookbook-5.5 根据内嵌的数字将字符串排序
任务 你想将一个字符串列表进行排序,这些字符串都含有数字的子串(比如一系列邮寄地址)。举个例子,“foo2.txt”应该出现在“foo10.txt”之前。然而,Python 默认的字符串比较是基于字母顺序的,所以默认情况下,“foo10.…...
EMC内参二(1-45页)学习【技术进阶】
EMC设计介入产品设计时间越早,成本越低。 微带线和带状线的区别: 微带线是PCB外层的走线,带状线是结余两个完整参考平面(电源层和地层)之间的走线。 天线效应: PCB上面任何悬空的金属都会积累电荷&…...
Ansible(7)——管理机密
目录 一、Ansible Vault : 二、ansible-vault 命令行工具: 1、创建加密文件: 2、查看加密文件: 3、编辑现有加密文件: 4、加密现有文件: 5、解密现有文件: 6、更改加密文件的密码&#…...
通俗地讲述DDD的设计
通俗地讲述DDD的设计 前言为什么要使用DDDDDD架构分层重构实践关键问题解决方案通过领域事件机制解耦服务依赖:防止逻辑下沉 领域划分电商场景下的领域划分 结语完结撒花,如有需要收藏的看官,顺便也用发财的小手点点赞哈,…...
【学Rust写CAD】34 精确 Alpha 混合函数(argb.rs补充方法)
源码 #[inline]pub fn over_exact(self, dst: Argb) -> Argb {let a 255 - self.alpha32();let t dst.rb() * a 0x80_00_80;let mut rb (t ((t >> 8) & Argb::MASK)) >> 8;rb & Argb::MASK;rb self.rb();// saturaterb | 0x1000100 - ((rb >&…...
10种电阻综合对比——《器件手册--电阻》
二、电阻 前言 10种电阻对比数据表 电阻类型 原理 特点 应用 贴片电阻 贴片电阻是表面贴装元件,通过将电阻体直接贴在电路板上实现电路连接 体积小、重量轻,适合高密度电路板;精度高、稳定性好,便于自动化生产 广泛应用于…...
SpringCloud入门及创建分布式项目
1、了解微服务 1.1 什么是微服务 微服务是一种架构风格一个应用拆分为一组小型服务每个服务运行在自己的进程内,也就是可独立部署和升级服务之间使用轻量级HTTP交互服务围绕业务功能拆分可以由全自动部署机制独立部署去中心化,服务自治。服务可以使用不同…...
xv6启动过程
entry,S -> start.c -> main.c -> proc.c中的 userinit 函数 -> initcode.S -> init.c entry.S // entry.S# qemu -kernel loads the kernel at 0x80000000# and causes each CPU to jump there.# kernel.ld causes the following code to# be placed at 0x800…...
【秣厉科技】LabVIEW工具包——OpenCV 教程(18):highgui 模块
文章目录 前言highgui 模块总结 前言 需要下载安装OpenCV工具包的朋友,请前往 此处 ;系统要求:Windows系统,LabVIEW>2018,兼容32位和64位。 highgui 模块 尽量别用,要不我删了吧? LabVIEW…...
基于OPENCV的图像透视矫正
这段代码的主要功能是对输入的图像进行透视矫正。它会读取一张图像,检测图像中最大的四边形轮廓,然后对该四边形区域进行透视变换,将其矫正为正视图,最后保存矫正后的图像。 模块导入说明 python import cv2 import numpy as n…...
数据结构----------顺序查找,折半查找和分块查找(java实现)
import java.util.Arrays;//顺序查找法 public class Main {public static void main(String[] args) {//查找表int[] arr {4, 3, 5, 1, 2};System.out.print("5在数组中的索引:");System.out.println(SearchSeq(arr, 5));Arrays.sort(arr);System.out.print("…...
整数编码 - 华为OD统一考试(A卷、JavaScript)
题目描述 实现一种整数编码方法,使得待编码的数字越小,编码后所占用的字节数越小。 编码规则如下: 编码时7位一组,每个字节的低7位用于存储待编码数字的补码。字节的最高位表示后续是否还有字节,置1表示后面还有更多的字节&…...
CompletableFuture:整合、超时、完成事件与批量处理
引言 在异步编程实践中,我们不仅需要处理单个任务的执行流程,更需要应对多个异步任务之间的复杂交互。本文将通过实际案例解析以下核心功能: 双任务整合:合并两个独立任务的结果高效超时控制:防止异步操作无限等待完…...
【LeetCode 热题100】45:跳跃游戏 II(详细解析)(Go语言版)
🚀 力扣 45:跳跃游戏 II(全解法详解) 📌 题目描述 给你一个非负整数数组 nums,表示你最初位于数组的第一个位置。 数组中的每个元素表示你在该位置可以跳跃的最大长度。 你的目标是使用 最少的跳跃次数 到…...
【C/C++】滑动谜题(leetcode T773)
核心考点:广度优先搜索 (BFS)、哈希表、字符串、状态转移 题目描述: 在一个 2 x 3 的板上(board)有 5 块砖瓦,用数字 1~5 来表示, 以及一块空缺用 0 来表示。一次 移动 定义为选择 0 与一个相邻的数字(上…...
python用x08覆盖上一次输出来模拟控制台等待效果,pycharm运行sys.stdout.write在控制台无打印的解决方法
一个多进程程序,主进程阻塞,子进程不断打印等待效果直到主进程结束,原理是\x08在ascii中表示退格键,理解为打印完后立马删掉打印下一个内容。 import sys, time import multiprocessing DELAY 0.1 DISPLAY [ |, /, -, \\ …...
【嵌入式开发】使用Linux系统调用编程练习
一、进程和线程的概念及基础用法 在Linux系统中,进程(Process)和线程(Thread)是操作系统进行任务调度的基本单位,它们既有联系又有区别。 1.1 进程和线程介绍 1.1.1 进程(Process)…...
React框架的Concurrent Mode
以下是关于 Concurrent Mode 的系统梳理: 一、Concurrent Mode 的诞生背景 传统渲染的局限性 同步阻塞:React 15 的 Stack Reconciler 无法中断渲染流程优先级缺失:用户交互与后台任务同等对待资源竞争:网络请求与渲染任务无法智能调度核心设计目标 可中断渲染:允许高优先…...
ER-图,详情和画法
一、E-R图的核心元素 1.实体 表示现实中对象或概念,用矩形表示 示例:用户、老师、学生 2.属性 描述实体的特征,用椭圆表示。 分为主键(用户id) 和非主键(用户昵称) 3.关系 表示实体间的…...
深度学习图像分类数据集—十种西红柿病态叶识别分类
该数据集为图像分类数据集,适用于ResNet、VGG等卷积神经网络,SENet、CBAM等注意力机制相关算法,Vision Transformer等Transformer相关算法。 数据集信息介绍:10种西红柿病态叶识别分类:Bacterial_spot,Earl…...