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

目录

分治

一、分治思想的概念

二、分治思想的步骤

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数组的下标。

总结:归并排序里面如果不涉及返回左边元素大于右边元素的具体个数,那么就不用考虑升序降序;如果涉及了考虑左边元素的某一个具体元素要比右边元素大多少个,那么就只能用降序,因为降序才包含right-cur2+1;但是升序就只包含mid-cur1+1,这个是对于右边元素大于nums[cur2] 这个数的次数,所以不是小于nums[cur1]的次数,即不一样
 

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 tmp[50001];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 mid=(left+right)/2;int ret=0;ret+=mergeSort(nums,left,mid);ret+=mergeSort(nums,mid+1,right);//一左一右int cur1=left,cur2=mid+1;while(cur1<=mid){while(cur2<=right&&nums[cur1]/2.0<=nums[cur2]) cur2++;if(cur2>right) break;ret+=right-cur2+1;cur1++;}//合并两个有序数组cur1=left,cur2=mid+1;int i=0;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;}
};

翻转堆
总结:
1.题目意思就是求数组里面有多少个当前的数字大于我后面的数字对,如果采用暴力枚举,就是O(N^2) 肯定会超时,那么就要想办法优化这个选数的规则

2.首先就是从排序下手,因为只有排序才会尽可能优化我们的算法,一次性求出多个满足条件的翻转对,就比如有序的情况下,利用下标相减,就可以直接得出哪两个数之间,是完全满足条件的,通过下标相减就可以得出

3.但是一般的比较快的排序都是不稳定的,唯独只有归并排序,他是稳定的,那么就可以从这里下手,第一,归并它稳定。第二归并它的效率高,时间复杂度是O(NlogN)

4.想好从归并后就可以开始举列子,康康是不是归并真的满足条件,那么就把数组分两块,可以先考虑降序的情况,当两块数组呈现降序的条件时,以cur1为主,来移动cur2,在cur2移动的过程中,nums[cur2]一直减小,直到某一个值时,nums[cur1]>nums[cur2]了,这个时候就可以开始计算满足条件的ret了

5.因为cur2左边的值都比nums[cur2]要小,但是nums[cur2]<nums[cur1] ,那么就说明【cur2,right】 这个区间的值都是小于nums[cur1]的,那么ret+=right-cur+1,就可以一次性判断此时nums[cur1]代表的值满足的所有条件

6.那么我们后面只需要再次移动cur1即可,移动后,可能又会出现nums[cur1]<nums[cur2]的情况,那么就只需要cur2++即可,让cur2不断跳过这些大于nums[cur1]的值,然后在开始计算下一个满足条件的nums[cur1]

7.上面是不同于其他的归并,这里讲合并数组给分开了,后面在进行两个有序数组的合并,从新让cur1 =left, cur2=mid+1,i=0,然后就是老方法进行数组合并,由于这题是降序,那么就把大的数先放进去,然后再将没有访问完的数组一次性放进去,最后就是还原 原数组nums 返回ret即可

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

14、线程池ForkJoinPool实战及其工作原理分析

1. 由一道算法题引发的思考 算法题&#xff1a;如何充分利用多核CPU的性能&#xff0c;快速对一个2千万大小的数组进行排序&#xff1f; 1&#xff09;首先这是一道排序的算法题&#xff0c;而且是需要使用高效的排序算法对2千万大小的数组进行排序&#xff0c;可以考虑使用快…

安卓13禁止待机 永不休眠 android13永不休眠

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改5.彩蛋1.前言 设置 =》显示 =》屏幕超时 =》 永不。 我们通过修改系统待机时间配置,来达到设置屏幕超时的配置。像网上好多文章都只写了在哪里改,改什么东西,但是实际上并未写明为什么要改那…

Redis的数据类型常用命令

目录 前言 String字符串 常见命令 set get mget mset setnx incr incrby decr decyby append Hash哈希 常见命令 hset hget hexists hdel hkeys hvals hgetall hmget hlen hsetnx List 列表 常见命令 lpush lrange lpushx rpush rpushhx lpop…

Mybtais高级结果映射-多对一表映射

前言 从前我们只进行单表的sql操作&#xff0c;但是如果涉及多张表的操作&#xff0c;原先的映射关系就不太适用了&#xff0c;因此这里将会介绍Mybatis的高级结果映射技巧 准备工作 准备两张数据库表&#xff0c;一个员工表&#xff0c;一个部门表&#xff08;我们使用oracle的…

一份转型大模型产品经理指南

作为一个产品经理&#xff0c;你可能已经熟悉了一些常见的AI技术和应用&#xff0c;比如机器学习、深度学习、自然语言处理、计算机视觉等。 但是&#xff0c;你是否了解什么是大模型&#xff1f;大模型又有什么特点和优势&#xff1f;为什么大模型会成为AI领域的一个重要趋势…

SQL语言入门

一、SQL语言入门&#xff1a; 数据库管理人员&#xff08;DBA&#xff09;通过数据库管理系统&#xff08;DBMS&#xff09;可以对数据库&#xff08;DB&#xff09;中的数据进行操作 SQL是一种非过程化语言&#xff0c;只需提出“做什么”&#xff0c;而不需要指明“怎么做”…

如何打造一个圈子社交系统?社交圈子论坛系统源码该如何实现

要打造一个圈子社交系统&#xff0c;并实现其源码&#xff0c;需要经历一系列详细的步骤&#xff0c;包括需求分析、系统设计、技术选型、开发、测试以及部署等。以下是一个全面的指南&#xff1a; 一、需求分析 明确目标用户&#xff1a;确定你的社交圈子面向哪类用户群体&a…

将U盘作为启动项报错:Verifying shim SBAT data failed: Security Policy Violation

问题描述 今天给新电脑装双系统的时候&#xff0c;将U盘设为启动项&#xff0c;总是报错&#xff0c;起初以为是启动盘做的有问题&#xff0c;报错如下&#xff1a; Verifying shim SBAT data failed: Security Policy Violation Something has gone seriously wrong: SBAT s…

栈的深度解析:顺序栈与链栈的实现

引言 栈是一种重要的线性数据结构&#xff0c;遵循“后进先出”&#xff08;LIFO&#xff09;的原则。栈的应用非常广泛&#xff0c;如表达式求值、括号匹配、递归实现等。在本文中&#xff0c;我们将深入探讨栈的概念&#xff0c;并通过顺序栈和链栈两种实现方式进行对比分析…

路径报错问题

项目场景&#xff1a; 假设这是我的项目结构&#xff0c;我现在需要在aa.js文件中引入并使用aa.geojson文件&#xff0c; 问题&#xff1a; 当我引入路径是const filePath ../geo/aa.geojson&#xff1b;的时候&#xff0c;系统报错 "aa.geojson is not Found",找不…

[000-002-01].第29节:MySQL执行流程

1、MySQL的查询流程&#xff1a; 客户端请求进入到数据库服务器后&#xff0c;先进行查询缓存&#xff0c;如果命中&#xff0c;那么就返回结果&#xff1b;如果没命中&#xff0c;进入到解析器&#xff0c;进行词法解析和语法解析&#xff0c;生成解析树&#xff1b;然后进入到…

企业图纸文档管理系统推荐 三大企业图纸文档管理软件详细介绍

在现代企业的设计和生产过程中&#xff0c;图纸文档的管理是至关重要的一环。 无论是建筑、制造业&#xff0c;还是技术研发领域&#xff0c;图纸文档的正确存储、分享与管理能够极大提升工作效率&#xff0c;避免误操作或信息丢失。 接下来&#xff0c;小编将为大家推荐三款优…

采购管理系统SRM助力电子元器件制造企业构建高效的供应商管理体系

在当今快速迭代的电子元器件制造行业中&#xff0c;构建一套高效、透明的供应商管理体系对于提升企业竞争力、降低运营成本、确保供应链稳定性至关重要。采购管理系统(SRM&#xff0c;Supplier Relationship Management)作为这一领域的得力助手&#xff0c;正引领着电子元器件制…

远程连接服务器时出现“这可能是由于CredSSP加密数据库修正”的错误提示的解决办法

现象&#xff1a; 当远程连接服务器时&#xff0c;有时候会出现以下提示&#xff0c;从而导致无法成功连接服务&#xff0c;如下所述&#xff1a; 原因&#xff1a; 远程桌面使用的是“凭据安全支持提供程序协议 (CredSSP) ”&#xff0c;这个协议在未修补的版本中是存在漏…

scrapy 爬取微博(四)【最新超详细解析】: 设计篇

一、功能设计 开始开发之前我们先对本文的scrapy微博爬虫工程进行一个功能的设计&#xff0c;包含的功能模块如下&#xff1a; 功能模块具体描述微博文章爬取根据关键词、时间范围等参数爬取微博文章&#xff0c;获取用户名、ID、微博mid、微博内容、点赞、转发、评论等数据微…

《深度学习》卷积神经网络 使用最优模型、调整学习率 用法解析及案例实现

目录 一、使用最优模型 1、什么是最优模型 2、如实使用最优模型 1&#xff09;读取参数方法 2&#xff09;调用完整模型方法 3&#xff09;实例 完整代码&#xff1a; 打印结果&#xff1a; 二、调整学习率 1、什么是调整学习率 2、目的 3、调整学习率的方法 1&am…

C++ 语言课程笔记

C 语言课程笔记 C语言程序设计第四版——谭浩强著&#xff0c;此书中的代码题大部分已经在本文中展示&#xff0c;以及南开大学 C 语言上机题库 100 题的作答&#xff0c;如果有作答不正确的地方或者可优化的地方&#xff0c;欢迎指正&#xff0c;谢谢&#xff01; 001 屏幕输出…

DAMODEL丹摩智算平台实践CogVideoX

文章目录 前言 一、平台账号注册并登录 二、部署CogVideoX &#xff08;一&#xff09;简介 &#xff08;二&#xff09;部署 1. 创建实例 2. 配置环境和依赖 3.预制模型与配置文件 三、开始运行 总结 前言 该文章主要记录DAMODEL丹摩智算平台实践过程与心得体会&…

【YashanDB知识库】客户端字符集与数据库字符集兼容问题

本文转自YashanDB官网&#xff0c;具体内容请见https://www.yashandb.com/newsinfo/7352675.html?templateId1718516 问题现象 客户端yasql配置字符集为GBK&#xff0c;服务端yasdb配置字符集为UTF8&#xff0c;之后执行语句&#xff1a; 会发现&#xff1a; 期望是两个都…

FAT32取证分析

前言&#xff1a; 在正常工作中经常会有数据恢复或者取证分析的场景&#xff0c;数据是否能被恢复&#xff0c;主要还是看数据是否被覆盖&#xff0c;正常情况下文件虽然被删除&#xff0c;只是修对应的标志位&#xff0c;文件本身数据并不会被破坏&#xff0c;所以我们就可以…