专题七_分治_快排_归并_算法专题详细总结

目录

分治

一、分治思想的概念

二、分治思想的步骤

1. 颜⾊分类(medium)

解析:

2. 快速排序(medium)

解析:

总结:

3. 快速选择算法(medium)

解析:

1)暴力:

2)优化:快速选择算法

总结:

4. 最⼩的 k 个数(medium)

解析:

1)暴力:

2)优化:快速选择排序

总结:

分治 - 归并排序

5. 归并排序(medium)

解析:

1)快排前面专题讲的很清楚,可以试试

2)堆排

3)归并排序

6. 归并排序(medium)

​编辑解析:

1)暴力:

2)优化:

1.左半部分跳完->右半部分->一左一右​编辑

2.左半部分跳完->左排序->右半部分跳完->右排序->一左一右 + 排序

3.通过2的排序,此时已经变成了一个归并排序来解决问题。

4.拓展:

总结:

7. 计算右侧⼩于当前元素的个数(hard)

解析:

1)暴力:

2)优化:分治_归并

总结:

8. 翻转对(hard)

解析:

归并排序:


分治

一、分治思想的概念

分治,即 “分而治之”。其核心思想是将一个复杂的问题分成若干个规模较小、相互独立且与原问题形式相同的子问题,分别求解这些子问题,然后将子问题的解合并起来,得到原问题的解。

二、分治思想的步骤

  1. 分解(Divide):

    • 将原问题分解为若干个规模较小、相互独立的子问题。这些子问题的形式与原问题相同,只是规模更小。
    • 例如,在归并排序中,将待排序的数组分成两个规模大致相等的子数组。
  2. 解决(Conquer):

    • 递归地求解各个子问题。如果子问题的规模足够小,则直接求解。
    • 对于归并排序,对子数组继续进行划分,直到子数组的长度为 1 或 2 时,直接进行排序。
  3. 合并(Combine):

    • 将子问题的解合并成原问题的解。
    • 在归并排序中,将两个已排序的子数组合并成一个有序的数组。

将一个大问题分解成许多个小问题,然后这些小问题在一一进行解决后合并,这种思想就像快排一一,是一个很好的切入点。

先来一道简单的例题,理解一下分治的简单思想,数组分三块,这里跟前面专题移动零一样运用双指针,这里多加了一个指针,也可以称为三指针,其中mid指针来分别将当前数组的元素跟left right位置的元素进行比较,然后进行交换。简单的分治思想将数组分三块,这里了解后,后面运用数组分三块思想真的很常见。

1. 颜⾊分类(medium)

题目意思就是让我们把数组有序排列,数组里面只有0 1 2三种元素

解析:

那么最开始想到的肯定就是三指针办法,定义left=-1 , mid=0 ,right=n,三个指针然后开始遍历数组,将数组分成三块

这里的数组就包含3种元素,0,1,2,那么1就可以当作是key值来让它跟nums[mid]进行比较。

如果nums[mid] < key , 就说明nums[mid]==0,要往前进行交换,那么就让left先往前走一步,两者就开始进行交换 mid就在往后走一步,即

if(nums[mid]<1) swap(nums[++left],nums[mid++]); 

如果nums[mid]==1,就证明此时mid指针正走在中间区域,那么就直接跳过就好,这又就是为什么要进行数组分三块,只有这样,才能将快排的时间复杂度降低,否则数组分两块,当整个数组全是重复元素的时候,时间复杂度就又退化到O(N^2) ,而数组分三块却只是O(N),只用遍历一遍。

else if(nums[mid]==1) mid++;

最后如果nums[mid]>key 那么就要跟最后面的right进行交换,先--right,防止越界,交换后,mid不能动,因为不能保证交换过来的数字是否满足条件,所以要重新判断

else swap(nums[--right],nums[mid]);

class Solution {
public:void sortColors(vector<int>& nums) {int left=-1,right=nums.size(),mid=0;while(mid<right){if(nums[mid]<1) swap(nums[++left],nums[mid++]);else if(nums[mid]==1) mid++;else swap(nums[--right],nums[mid]);}}
};

总结:

相对来说这题比较简单,数据量也比较少,只用考虑 0 1 2的位置关系

了解数组分三块后,我们就开始进行分治,可能我们只进行一趟,不能够满足我们的条件,只是把==key的值放在它正确的位置,而左右两边只是无序的小于key值 或大于key值,那么我们进行递归操作,就可以完成整个数组的排序任务。

2. 快速排序(medium)

题意很简单,就是在O(nlogn)下完成排序,那么首先想到的就是快排,也是本章分治思想。

解析:

这里分治思想体现的淋漓尽致,那么我们只需要想上一题一样,数组分三块,然后进行排序交换,后面再递归给出我的子数组的范围,只要达到结束条件(left>=right) 即可返回整个数组。

快排,数组分三块思想,这样可以将数组分两块的不足给避免
当数组分两块:如果数组里面全部都是相同的元素,那么时间复杂度就会降低到O(N^2)

当数组分三块,那么数组内就会变成【小于key值的元素】  【==key值的元素】  【大于key值的元素】  那么当数组内全部都是相同元素的时候,就可以只移动mid指针,之对数组进行一次遍历,时间复杂度为O(N^2)  当一趟排序完成后,那么就进行递归,因为给的范围是【l,r】 那么要创建移动的 指针left,right,mid,来表示left和right最终移动的位置,然后就可以得出递归的范围,因为【left+1,right-1】 是==key的元素,那么【l,left】 【right,r】 的两个范围就要继续进行递归完成

最后就是随机数,用srand(time(NULL)) 来种下一颗随机数的种子,然后获取随机数int r=rand() 然后以免取得的随机数下标越界,那么就要对小标进行控制在[l,r]之间r%(right-left+1)+left

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 left=l-1,right=r+1,mid=l;//获得随机数int key=getRand(nums,l,r);while(mid<right){if(nums[mid]<key) swap(nums[++left],nums[mid++]);else if(nums[mid]==key) mid++;else swap(nums[--right],nums[mid]);}//递归//[l,left] [left+1,right-1] [right,r]qsort(nums,l,left);qsort(nums,right,r);}int getRand(vector<int>& nums,int left,int right){int r=rand();return nums[r%(right-left+1)+left];}
};

总结:

这个代码真的很完美强烈建议默写一百遍!随机取值,数组分三块~

3. 快速选择算法(medium)

这题也是本个章节的重点,topK问题

解析:

1)暴力:

肯定就是先将数组完全排序好后,然后再返回第k大的元素,但是题目要求O(N) 所以如果排序就成了O(NlogN)

2)优化:快速选择算法

快速选择算法也可以认为是快排的一种小变形,只是返回的是特定的值或者区间,所以没有必要完全将数组排完序后再进行返回,那么这样就可以有效的降低时间复杂度

求出数组中第K个最大元素,在时间复杂度达到O(N)的条件下,首先就该考虑快排,将数组分三块,能够很接近O(N) 

那么这一题只是求出数组第K个最大的元素,只要返回那一个值就行,那么最开始我就是运用快排,然后返回k大的下标,后来发现确实也可以不用全部都排完序后在返回,可以排完k大的数后直接返回即可。

数组分三块【<key】 【==key】  【>key】 
1) 当大于key的数组里面排序在[right,r]之间数字个数为k的时候就直接返回
2)当大于key的数字个数不够k个,那就再加上==key的数字个数大于等于k个的时候就返回key
3)当==key和>key的数字个数和都小于k,那么就要到<key里面去找满足条件的,
 

class Solution {
public:int findKthLargest(vector<int>& nums, int k) {srand(time(nullptr));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 left=l-1,right=r+1,mid=l;int key=getRand(nums,l,r); while(mid<right){if(nums[mid]<key) swap(nums[++left],nums[mid++]);else if(nums[mid]==key) mid++;else swap(nums[--right],nums[mid]);}//分情况讨论: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 getRand(vector<int>& nums,int left,int right){int r=rand();return nums[r%(right-left+1)+left];}
};

总结:

这题是跟上题快排大差不差,唯一不同就是再最后的递归部分,考虑清除边界条件

b=right - 1 - (left + 1) +1 = right - left - 1;

//分情况讨论:
        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);

4. 最⼩的 k 个数(medium)

这一题仍然是TopK问题,那么这题正好跟上一题相反,找到最小的k个数

解析:

1)暴力:

仍然就是快排后返回数组

2)优化:快速选择排序

快速选择排序,仍然是topK问题,不用完全排序只需要排序排个大概,了解大概元素的分布,前几个元素在哪,然后直接返回,时间复杂度O(N),但是其实我觉得还是排序方便O(NlogN) 只要你排好序了,想怎么返回就怎么返回

class Solution {
public:vector<int> inventoryManagement(vector<int>& nums, int k) {srand(time(nullptr));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;int left=l-1,right=r+1,mid=l;int key=getRand(nums,l,r);while(mid<right){if(nums[mid]<key) swap(nums[++left],nums[mid++]);else if(nums[mid]==key) mid++;else swap(nums[--right],nums[mid]);}//求[<key] [==key] [>key] 的个数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 getRand(vector<int>& nums,int left,int right){return nums[rand()%(right-left+1)+left];}
};

总结:

想着一系列TopK问题都是利用数组分三块,然后在递归部分来进行缩小范围,直到满足结束条件,最后终止。

分治 - 归并排序

5. 归并排序(medium)

题目意思就是排序这个数组,但是我们这个专题采用归并的思想来进行,将大数组分成小数组,然后合并已经排好序的小数组。

解析:

1)快排
前面专题讲的很清楚,可以试试

2)堆排

也是很不错的排序O(NlogK)

3)归并排序

将大数组分成一小份一小份的小数组,然后对小数组进行排序,再将两个小数组进行归并,一直取较小的值合并到原数组中。

然后对没有排完的数组进行剩余的加入,最后再将排好序数组放入到原数组里。

 //快排版

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 left=l-1,right=r+1,mid=l;//获得随机数int key=getRand(nums,l,r);while(mid<right){if(nums[mid]<key) swap(nums[++left],nums[mid++]);else if(nums[mid]==key) mid++;else swap(nums[--right],nums[mid]);}//递归//[l,left] [left+1,right-1] [right,r]qsort(nums,l,left);qsort(nums,right,r);}int getRand(vector<int>& nums,int left,int right){int r=rand();return nums[r%(right-left+1)+left];}
};

//归并版

class Solution {
public:vector<int> sortArray(vector<int>& nums) {mergeSort(nums,0,nums.size()-1);return nums;}void mergeSort(vector<int>& nums,int left,int right){if(left>=right) return;int mid=(left+right)/2;mergeSort(nums,left,mid);mergeSort(nums,mid+1,right);vector<int> tmp(right-left+1);//合并两个有序数组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(int i=left;i<=right;i++) nums[i]=tmp[i-left];//tmp从0开始计数}
};

6. 归并排序(medium)

求解数组里面前一个数大于后一个数的 对数。

解析:

1)暴力:

就是两层for循环来暴力枚举所有两个数之间的情况,符合ret++,但是肯定会超时

2)优化:

先将数组分两块,

1.左半部分跳完->右半部分->一左一右

2.左半部分跳完->左排序->右半部分跳完->右排序->一左一右 + 排序

3.通过2的排序,此时已经变成了一个归并排序来解决问题。

算法原理:数组程升序状态

策略一:找出该数之前,有多少个数比我大

4.拓展:

为什么这题要用升序数组?不能用降序数组吗?降序数组就没有作用吗?

那么思考再什么情况下利用降序比较合理呢?

策略二:找出该数之后,有多少个数比我小(适合用降序)

因为采用降序,nums[cur1] 是第一次比nums[cur2]要大的,所以就完全可以计算出cur2后面所有元素的个数,因为cur2 前面的元素都要比cur1要大。

class Solution {
public:int tmp[50001];int reversePairs(vector<int>& record) {return mergeSort(record,0,record.size()-1);}int mergeSort(vector<int>& nums,int left,int right){if(left>=right) return 0;int ret=0;int mid=(left+right)/2;//1.左统计+左排序ret+=mergeSort(nums,left,mid);//2.右统计+右排序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++];for(int j=left;j<=right;j++) nums[j]=tmp[j-left];return ret;}
};

总结:

首先由数组能不能分成小块进行引入,如果可以,那么就分小块进行,这样讲整体细化成一个个小问题。再从这里想到对数组划分后能不能进行排序,想到分治归并上。主要就是要明白再挑选一左一右统计次数的时候要分清什么情况下是可以一次统计完所有次数的,大体思路就跟归并没什么两样。

7. 计算右侧⼩于当前元素的个数(hard)

读完题发现这题简直跟上一题求逆序对的个数一模一样,唯一的难点就是要求,求出每一个小于数字的个数然后存入数组内。

解析:

1)暴力:

两层for()循环,肯定会超时的

2)优化:分治_归并

这一题就是运用上一题的策略二:当前元素的后面有多少个比我小的元素

这里需要讲nums数组的下标进行绑定到index数组里面

class Solution {vector<int> ret;vector<int> index; // 记录 nums 中当前元素的原始下标int tmpNums[500010];int tmpIndex[500010];public:vector<int> countSmaller(vector<int>& nums) {int n = nums.size();ret.resize(n);index.resize(n);// 初始化⼀下 index 数组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;int mid = (left + right) >> 1;// 先搞搞左边,在搞搞右边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++];} 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];}}
};

总结:

这题跟上一题大差不差,唯一不同的就是要多创建一个数组index来绑定nums数组的下标。

8. 翻转对(hard)

这一题跟逆序对超级一样,题目意思就是说前面的数要大于后面数的两倍

解析:

归并排序:

在归并排序的过程中,假设对于数组 nums[l..r] 而言,我们已经分别求出了子数组 nums[l..m] 与 nums[m+1..r] 的翻转对数目,并已将两个子数组分别排好序,则 nums[l..r] 中的翻转对数目,就等于两个子数组的翻转对数目之和,加上左右端点分别位于两个子数组的翻转对数目。

我们可以为两个数组分别维护指针 i,j。对于任意给定的 i 而言,我们不断地向右移动 j,直到 nums[i]≤2⋅nums[j]。此时,意味着以 i 为左端点的翻转对数量为 j−m−1。随后,我们再将 i 向右移动一个单位,并用相同的方式计算以 i 为左端点的翻转对数量。不断重复这样的过程,就能够求出所有左右端点分别位于两个子数组的翻转对数目。

 

class Solution {
public:int reversePairsRecursive(vector<int>& nums, int left, int right) {if (left == right) {return 0;} else {int mid = (left + right) / 2;int n1 = reversePairsRecursive(nums, left, mid);int n2 = reversePairsRecursive(nums, mid + 1, right);int ret = n1 + n2;// 首先统计下标对的数量int i = left;int j = mid + 1;while (i <= mid) {while (j <= right && (long long)nums[i] > 2 * (long long)nums[j]) j++;ret += (j - mid - 1);i++;}// 随后合并两个排序数组vector<int> sorted(right - left + 1);int p1 = left, p2 = mid + 1;int p = 0;while (p1 <= mid || p2 <= right) {if (p1 > mid) {sorted[p++] = nums[p2++];} else if (p2 > right) {sorted[p++] = nums[p1++];} else {if (nums[p1] < nums[p2]) {sorted[p++] = nums[p1++];} else {sorted[p++] = nums[p2++];}}}for (int i = 0; i < sorted.size(); i++) {nums[left + i] = sorted[i];}return ret;}}int reversePairs(vector<int>& nums) {if (nums.size() == 0) return 0;return reversePairsRecursive(nums, 0, nums.size() - 1);}
};

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

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

相关文章

xinference linux系统下部署

1.创建虚拟环境 conda create -n xinfer pyrhon3.10 2.使用虚拟环境 conda activate xinfer (xinfer) roothome:~$ python -V Python 3.10.14 3.pip安装环境 pip install "xinference[all]" 4.启动服务 nohup xinference-local --host 0.0.0.0 --port 9997 &…

认识结构体

目录 一.结构体类型的声明 1.结构的声明 2.定义结构体变量 3.结构体变量初始化 4.结构体的特殊声明 二.结构体对齐(重点难点) 1.结构体对齐规则 2.结构体对齐练习 (一)简单结构体对齐 (二)嵌套结构体对齐 3.为什么存在内存对齐 4.修改默认对齐数 三.结构体传参 1…

python新手的五个练习题

代码 # 1. 定义一个变量my_Number,将其设置为你的学号&#xff0c;然后输出到终端。 my_Number "20240001" # 假设你的学号是20240001 print("学号:", my_Number) # 2. 计算并输出到终端:两个数(例如3和5)的和、差、乘积和商。 num1 3 num2 5 print(&…

nacos适配人大金仓的数据库

前言 在微服务架构中&#xff0c;服务发现和配置管理是关键组件。Nacos作为一个动态服务发现和配置管理平台&#xff0c;支持多种数据库作为其后端存储。本文将探讨如何在Nacos中适配人大金仓数据库&#xff0c;以及在此过程中的最佳实践。 Nacos简介 Nacos&#xff08;Nami…

安卓数据存储——SharedPreferences

共享参数 SharedPreferences 1、sharedPreferences是Android的一个轻量级存储工具&#xff0c;采用的存储结构是key - value的键值对方式 2、共享参数的存储介质是符合XML规范的配置文件。保存路径是&#xff1a;/data/data/应用包名/shared_prefs/文件名.xml 使用场景&…

[Python学习日记-26] Python 中的文件操作

[Python学习日记-26] Python 中的文件操作 简介 操作模式 循环文件 其他功能 混合模式 修改文件 简介 在 Python 中的文件操作其实和我们平时使用的 Word 的操作是比较类似的&#xff0c;我们先说一下 Word 的操作流程&#xff0c;流程如下&#xff1a; 找到文件&#x…

LeetCode题练习与总结:回文链表--234

一、题目描述 给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为回文链表。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,2,1] 输出&#xff1a;true示例 2&#xff1a; 输入&#x…

【笔记】第三节 组织与性能

3.1 基本成分 3.2 微观组织特征 0.6-0.8C%碳素钢的组织为珠光体和少量的铁素体。 如何把组织和性能联系起来&#xff1f;德国克虏伯公司的研究——珠光体片间距与渗碳体片层厚度成比例&#xff1a; t s 0 ( ρ 15 ( C % ) − 1 ) ts_0(\frac{\rho}{15(C\%)}-1) ts0​(15(C%)…

go的结构体、方法、接口

结构体&#xff1a; 结构体&#xff1a;不同类型数据集合 结构体成员是由一系列的成员变量构成&#xff0c;这些成员变量也被称为“字段” 先声明一下我们的结构体&#xff1a; type Person struct {name stringage intsex string } 定义结构体法1&#xff1a; var p1 P…

谷歌收录批量查询,怎么查看批量查询谷歌收录情况

在SEO&#xff08;搜索引擎优化&#xff09;领域&#xff0c;确保网站内容被谷歌等搜索引擎有效收录是提升网站可见性和流量的关键步骤。批量查询谷歌收录情况&#xff0c;能够帮助网站管理员快速了解哪些页面已被搜索引擎识别并编入索引&#xff0c;哪些页面可能存在问题需要优…

SpringBoot项目License证书生成与验证(TrueLicense) 【记录】

SpringBoot项目License证书生成与验证(TrueLicense) 【记录】 在非开源产品、商业软件、收费软件等系统的使用上&#xff0c;需要考虑系统的使用版权问题&#xff0c;不能随便一个人拿去在任何环境都能用。应用部署一般分为两种情况&#xff1a; 应用部署在开发者自己的云服务…

变电站缺陷数据集8307张,带xml标注和txt标注,可以直接用于yolo训练

变电站缺陷数据集8307张&#xff0c; 带xml标注和txt标注&#xff0c;可以直接用于yolo训练&#xff0c;赠附五个脚本 变电站缺陷数据集 数据集概述 变电站缺陷数据集是一个专门针对变电站设备和环境缺陷检测的图像数据集。该数据集包含了8307张经过标注的图像&#xff0c;旨…

Java 入门指南:JVM(Java虚拟机)垃圾回收机制 —— 垃圾收集器

文章目录 垃圾回收机制Stop-the-World垃圾收集器垃圾收集器分类Serial 收集器Serial Old 收集器ParNew 收集器Parallel Scavenge 收集器Parallel Old 收集器CMS 收集器CMS 收集器缺点 G1 收集器G1 收集器特点G1 收集器的分代理念G1 收集器运作过程 垃圾回收机制 垃圾回收&…

【Linux笔记】如何将内容从一个文件复制到另一个文件

比如&#xff1a;将文件tmp_file.txt中的部分数据&#xff0c;复制到file01.txt中去 tmp_file.txt文中内容&#xff1a; file01.txt为空文档 一、使用vi编辑器 I、文件中直接使用:e 目标文件进行切换文件复制 1、打开被复制文件 vi tmp_file.txt 2、进入一般命令模式 默认情况为…

排序-----归并排序(递归版)

核心思想&#xff1a;假设数组前后两部分各自有序&#xff0c;然后各定义两个指针&#xff0c;谁小谁放到新开辟的数组里面&#xff0c;最后把新开辟的数组赋值给原数组就完成了。要使前后两部分有序就采用递归的方式&#xff0c;不断往下划分块&#xff0c;最后一层划分为两个…

SVM原理

SVM 这里由于过了很长时间 博主当时因为兴趣了解了下 博主现在把以前的知识放到博客上 作为以前的学习的一个结束 这些东西来自其他资料上 小伙伴看不懂英文的自行去翻译下吧 博主就偷个懒了 多维空间和低维空间 不一样的分法&#xff0c;将数据映射到高维 &…

鸿蒙OpenHarmony【轻量系统内核扩展组件(动态加载)】子系统开发

基本概念 在硬件资源有限的小设备中&#xff0c;需要通过算法的动态部署能力来解决无法同时部署多种算法的问题。以开发者易用为主要考虑因素&#xff0c;同时考虑到多平台的通用性&#xff0c;LiteOS-M选择业界标准的ELF加载方案&#xff0c;方便拓展算法生态。LiteOS-M提供类…

ZYNQ学习--AXI总线协议

一、AXI 总线简介 AXI&#xff08;Advanced Extensible Interface&#xff09;高级拓展总线是AMBA&#xff08;Advanced Microcontroller Bus Architecture&#xff09;高级微控制总线架构中的一个高性能总线协议&#xff0c;由ARM公司开发。AXI总线协议被广泛应用于高带宽、低…

PyQt5 导入ui文件报错 AttributeError: type object ‘Qt‘ has no attribute

问题描述&#xff1a; 利用 PyQt5 编写可视化界面是较为普遍的做法&#xff0c;但是使用全新UI版本的 Pycharm 修改之前正常的UI文件时&#xff0c;在没有动其他代码的情况下发现出现以下报错 AttributeError: type object Qt has no attribute Qt::ContextMenuPolicy::Defaul…

JavaEE: 深入探索TCP网络编程的奇妙世界(四)

文章目录 TCP核心机制TCP核心机制四: 滑动窗口为啥要使用滑动窗口?滑动窗口介绍滑动窗口出现丢包咋办? TCP核心机制五: 流量控制 TCP核心机制 上一篇文章 JavaEE: 深入探索TCP网络编程的奇妙世界(三) 书接上文~ TCP核心机制四: 滑动窗口 为啥要使用滑动窗口? 之前我们讨…