当前位置: 首页 > news >正文

归并排序算啊模板and三道困难级别的归并力扣算法题--LCR170,493,315

目录

归并排序算法模板:

1.1题目链接:LCR.170.交易逆序对的总数

1.2题目描述:

1.3解法(利用归并排序的过程--分治):

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

2.2题目描述:

2.3解法:

3.1题目链接:493.翻转对

3.2题目描述:

3.3解法:


归并排序算法模板:

class Solution {
public:vector<int> ret;vector<int> sortArray(vector<int>& nums) {ret.resize(nums.size());mergesort(nums,0,nums.size()-1);return ret;}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)ret[i++] = nums[cur1] <= nums[cur2]?nums[cur1++]:nums[cur2++];//处理没有遍历完的数组while(cur1<=mid)ret[i++] = nums[cur1++];while(cur2<=right)ret[i++] = nums[cur2++];//4.还原for(int i = left;i<=right;i++)nums[i] = ret[i-left];}
};

1.1题目链接:LCR.170.交易逆序对的总数

1.2题目描述:

在股票交易中,如果前一天的股价高于后一天的股价,则可以认为存在一个「交易逆序对」。请设计一个程序,输入一段时间内的股票交易记录 record,返回其中存在的「交易逆序对」总数。

示例 1:

输入:record = [9, 7, 5, 4, 6]
输出:8
解释:交易中的逆序对为 (9, 7), (9, 5), (9, 4), (9, 6), (7, 5), (7, 4), (7, 6), (5, 4)。

提示:

0 <= record.length <= 50000

1.3解法(利用归并排序的过程--分治):

算法思路:

用归并排序求逆序数是很经典的问题,主要就是在归并排序的合并过程中统计出逆序对的数量,也就是在合并两个有序序列的过程中,能够快速求出逆序对的数量。

我们将这个问题分解成几个小问题,逐一破解这道题。

注意:默认都是升序,如果掌握升序的话,降序的归并过程也是可以解决解决问题的。

  • 先解决第一个问题:为什么可以用归并排序?

如果我们将数组从中间划分成两个部分,那么我们可以将逆序对产生的方式划分成三组:

  • 逆序对中两个元素:全部从左数组中选择
  • 逆序对中两个元素:全部从右数组中选择
  • 逆序对中两个元素:一个选左数组另一个选右数组

根据排列组合的分类相加原理,三种情况下产生的逆序对的总和,正好等于总的逆序对数量。

而这个思路正好匹配归并排序的过程:

  • 先排序左数组;
  • 再排序右数组
  • 左数组和有数组合二为一。

因此,我们可以利用归并排序的过程,先求出左半数组中逆序对的数量,再求出右半数组逆序对的数量,最后求出一个选择左边,另一个选择右边情况下逆序对的数量,三者相加即可。

  • 解决第二个问题,为什么要这么做?

在归并排序合并的过程中,我们得到的是两个有序的数组。我们是可以利用数组的有序性,快速统计出逆序对的数量,而不是将所有情况都枚举出来。

  • 最核心的问题,如何在合并两个有序数组的过程中,统计出逆序对的数量?

合并两个有序序列时求逆序对的方法有两种:

  1. 快速统计出某个数前面有多少个数比它大;
  2. 快速统计出某个数后面有多少个数比它小;

快速统计出某个数前面有多少个数比它大

通过一个实例来演示方法一:
假定已经有两个已经有序的序列以及辅助数组left = [5,7,9] right = [4,5,8] help=[],通过合并两个有序数组的过程,来求得逆序对的数量:

规定如下定义来叙述过程:

        cur1遍历left数组,cue2遍历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],因此right[cur2]可能与left数组中往后的元素构成逆序对,因此我们需要将left[cur1]加入到辅助数组中去,此时没有产生逆序对,不更新ret。

第二轮循环结束后:left = [x,7,9] right = [x,5,8] help[4,5] ret = 3 cur1 = 1 cur2 = 1

第三轮循环:

        left[cur1] < right[cur2],与第一轮虚幻相同,此刻left数组中[cur1,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)

由上述过程我们可以得出方法一统计逆序对的关键点:

合并有序数组的时候,遇到左数组当前元素>右数组当前元素时,我们可以通过计算左数组中剩余元素的长度,就可快速求出右数组当前元素前面有多少个数比它大,对比解法一中一个一个枚举逆序对效率快了许多。

升序:

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;//[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++];}}//4.处理一个排序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;}
};

降序:

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;//[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[cur2++];}else{ret += right - cur2 + 1;tmp[i++] = nums[cur1++];}}//4.处理一个排序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;}
};

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

2.2题目描述:

给你一个整数数组 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 个更小的元素

示例 2:

输入:nums = [-1]
输出:[0]

示例 3:

输入:nums = [-1,-1]
输出:[0,0]

提示:

  • 1 <= nums.length <= 10^5
  • -10^4 <= nums[i] <= 10^4

2.3解法:

算法思路:

这一道题的解法与上一道题的解法是类似的,但是这一道题要求的不是求总的个数,而是要返回一个数组,记录每一个元素的右边有多少个元素比自己小。

但是在我们归并排序的过程中,元素的下标是会跟着变化的,因此我们需要一个辅助数组,来将数组元素和对应的下标捆绑在一起归并,也就是再归并元素的时候,顺势将下标也转移到对应的位置上。

算法流程:

  • 创建两个全局的数组:

        vector<int>index:记录下标

        vector<int>ret:记录结果

index用来与原数组中对应位置的元素绑定,ret用来记录每个位置统计出来的逆序对的个数。

  • countSmaller()主函数:
  1. 计算nums数组的大小为n;
  2. 初始化定义的两个全局的数组;(为两个数组开辟大小为n的空间;index初始化为数组小标;ret初始化为0)
  3. 调用mergeSort()函数,并且返回ret结果数组。
  • void mergeSort(vector<int>& nums, int left, int right)函数:

函数设计:通过修改全局的数组ret,统计出每一个位置对应的逆序对的数量,并且排序;无需返回值,因为直接对全局变量修改,当函数结束的时候,全局变量已经被修改成最后的结果。

  • mergeSort()函数流程:
  1. 定义递归出口:left>=right时,直接返回;
  2. 划分区间:根据中点mid,将区间划分为[left,mid]和[mid+1,right];
  3. 统计左右两个区间逆序对的数量:统计左边区间[left,mid]中每个元素对应的逆序对的数量到ret数组中,并排序;统计右边区间[mid+1,right]中每个元素对应的逆序对的数量到ret数组中,并排序。
  4. 合并左右两个有序区间,并且统计出逆序对的数量:                                                     创建两个大小为right-left+1大小的辅助数组:tmpnums:排序用的辅助数组;                                                                                      tmpindex:处理下标用的辅助数组           

        初始化遍历数组的指针:cur1 = left(遍历左半部分数组) cur2 = mid+1(遍历右半边数组) dest = 0(遍历辅助数组)curRet(记录合并时产生的逆序对的数量);                       

        循环合并区间:

  • 当nums[cur1] <= nums[cur2]时:
    无需统计,直接归并,注意index也要跟住归并。
  • 当nums[cur1] > nums[cur2]时:

        说明此时[cur2,right]之间的元素都是小于nums[cur1]的,需要累加到ret数组的index[cur1]位置上(因为index存储的是元素对应位置在原数组中1的下标)

        归并排序:不仅要将数据放在对应的位置上,也要将数据对应的坐标也放在对应的位置上,使数据与原始的下标绑定在一起移动

        处理归并排序中剩余的元素;

        将辅助数组的内容替换到原数组中去;

class Solution {
public:vector<int> index;  //记录nums中当前元素的原始下标vector<int> ret;int tmpNums[500010];int tmpIndex[500010];vector<int> countSmaller(vector<int>& nums) {int n = nums.size();ret.resize(n);index.resize(n);//初始化一下indexfor(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)>>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){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 i = left;i<=right;i++){nums[i] = tmpNums[i-left];index[i] = tmpIndex[i-left];}}
};

3.1题目链接:493.翻转对

3.2题目描述:

给定一个数组 nums ,如果 i < j 且 nums[i] > 2*nums[j] 我们就将 (i, j) 称作一个重要翻转对

你需要返回给定数组中的重要翻转对的数量。

示例 1:

输入: [1,3,2,3,1]
输出: 2

示例 2:

输入: [2,4,3,5,1]
输出: 3

注意:

  1. 给定数组的长度不会超过50000
  2. 输入数组中的所有数字都在32位整数的表示范围内。

3.3解法:

算法思路:
大思路与求逆序对的思路一样,就是利用归并排序的思想,将求整个数组的翻转对的数量,转换成三部分:左半区间翻转对的数量,右半区间翻转对的数量,一左一右选择时翻转对的数量。重点就是在合并区间过程中,如何计算出翻转对的数量。
与上个问题不同的是,上一道题我们可以一边合并一遍计算,但是这道题要求的是左边元素大于右边元素的两倍,如果我们直接合并的话,是无法快速计算出翻转对的数量的。
例如 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*rightlcur2]。不断重复这样的过程,就能够求出所有左右端点分别位于两个子数组的翻转对数目。
由于两个指针最后都是不回退的的扫描到数组的结尾,因此两个有序序列求出翻转对的时间复杂度是O(N)。
综上所述,我们可以利用归并排序的过程,将求一个数组的翻转对转换成求左数组的翻转对数量+右数组中翻转对的数量+左右数组合并时翻转对的数量。

降序版本:
 

class Solution {
public:vector<int> tmp;int reversePairs(vector<int>& nums) {tmp.resize(nums.size());    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)>>1;int ret = 0;ret += MergeSort(nums,left,mid);ret += MergeSort(nums,mid+1,right);int cur1 = left, cur2 = mid+1, i = left;while(cur1 <= mid){while(cur2 <= right && nums[cur2]>=nums[cur1]/2.0)cur2++;if(cur2>right)break;ret += right - cur2 + 1;cur1++;}cur1 = left,cur2 = mid+1,i=0;while(cur1 <= mid & cur2 <= right){if(nums[cur1]<=nums[cur2]){tmp[i++] = nums[cur2++]; }else {tmp[i++] = nums[cur1++];}}while(cur1 <= mid){ret += right-cur2+1;tmp[i++] = nums[cur1++];}while(cur2 <= right){tmp[i++] = nums[cur2++]; }//还原for(int i = left;i<=right;i++)nums[i] = tmp[i-left];return ret;}
}; 

相关文章:

归并排序算啊模板and三道困难级别的归并力扣算法题--LCR170,493,315

目录 归并排序算法模板&#xff1a; 1.1题目链接&#xff1a;LCR.170.交易逆序对的总数 1.2题目描述&#xff1a; 1.3解法(利用归并排序的过程--分治)&#xff1a; 2.1题目链接&#xff1a;315.计算右侧小于当前元素的个数 2.2题目描述&#xff1a; 2.3解法&#xff1a; …...

鸿蒙 harmonyOS:项目实战 :倒计时器

代码&#xff1a; import { promptAction } from kit.ArkUIEntry Component struct Index {State count: number 10 // 初始倒计时秒数State timerId: number -1 // 定时器ID// 开始倒计时startCountdown() {if (this.timerId -1) {this.timerId setInterval(() > {if …...

31--当认证协议开始“选秀“:RADIUS、LDAP、AD与本地认证的C位之争

当认证协议开始"选秀"&#xff1a;RADIUS、LDAP、AD与本地认证的C位之争 引言&#xff1a;认证界的"四大天王" 如果把企业网络比作夜店&#xff0c;那么身份认证就是门口的黑衣保安。不同风格的保安队长各有绝活&#xff1a; RADIUS像特种兵出身的安检专家…...

AI 数理逻辑基础之统计学基本原理(上)

目录 文章目录 目录统计学统计学基本概念描述性统计数据可视化图表工具 汇总统计统计数据的分布情况&#xff1a;中位数、众数、平均值统计数据的离散程度&#xff1a;极差、方差、标准差、离散系数 相关分析Pearson 线性关系相关系数Spearman 单调关系相关系数 回归分析回归模…...

C++容器数据类型定义、测试用例

C11 标准库提供了多种容器类型&#xff0c;每种容器定义了多个成员类型&#xff08;如 value_type、iterator 等&#xff09;&#xff0c;用于与容器交互。以下详细说明各容器的数据类型定义、测试用例及注意事项。 一、顺序容器 1. std::vector<T> 类型定义&#xff1…...

bun 版本管理工具 bum 安装与使用

在使用 node 的过程中&#xff0c;我们可能会因为版本更新或者不同项目的要求而频繁切换 node 版本&#xff0c;或者是希望使用更简单的方式安装不同版本的 node&#xff0c;这个时候我们一般会用到 nvm 或者类似的工具。 在我尝试使用 bun 的时候&#xff0c;安装前第一个想到…...

AI——使用numpy

文章目录 一、numpy的介绍1、ndarray介绍2、ndarray使用1、ndarray的属性2、ndarray生成数组的方法 3、修改数组的形状4、修改数组的类型5、数组去重 二、数组的运算1、逻辑运算2、通用判断函数3、三元运算符4、统计运算 三、数组间运算四、数学&#xff1a;矩阵 一、numpy的介…...

在线追思:一个虚拟扫墓平台,让思念不受时空限制

在线追思&#xff1a;一个虚拟扫墓平台&#xff0c;让思念不受时空限制 &#x1f4e2; 重要分享 今天想与大家分享一个特别的网站——在线追思平台。这是一个让我们能随时随地表达对逝者思念之情的虚拟扫墓平台。 &#x1f31f; 为什么需要在线追思&#xff1f; 在现代生活的…...

Visual Basic语言的网络协议栈

Visual Basic语言的网络协议栈 引言 在当今信息技术高速发展的时代&#xff0c;网络通信已经成为各类应用程序中不可或缺的部分。无论是网页浏览、文件传输&#xff0c;还是即时通讯&#xff0c;网络协议的有效实现都是保证数据顺利传输和信息安全的重要基础。在这种背景下&a…...

python速通小笔记-------4.Pandas库

1.pandas介绍 1.一维数组的创建 1.字典创建法-----------pd.Series(字典&#xff09; 使用pd.Series(),参数为已经创建好了的字典 2.数组创建法-----------pd.Series(列表1&#xff0c;index列表2&#xff09; 2.一维对象的属性 sr.values----------查看所有的vsr.index----…...

P7453 [THUSC 2017] 大魔法师 Solution

Description 给定序列 a ( a 1 , a 2 , ⋯ , a n ) a(a_1,a_2,\cdots,a_n) a(a1​,a2​,⋯,an​)&#xff0c; b ( b 1 , b 2 , ⋯ , b n ) b(b_1,b_2,\cdots,b_n) b(b1​,b2​,⋯,bn​) 和 c ( c 1 , c 2 , ⋯ , c n ) c(c_1,c_2,\cdots,c_n) c(c1​,c2​,⋯,cn​)&…...

小程序API —— 58 自定义组件 - 创建 - 注册 - 使用组件

目录 1. 基本介绍2. 全局组件3. 页面组件 1. 基本介绍 小程序目前已经支持组件化开发&#xff0c;可以将页面中的功能模块抽取成自定义组件&#xff0c;以便在不同的页面中重复使用&#xff1b;也可以将复杂的页面拆分成多个低耦合的模块&#xff0c;有助于代码维护&#xff1…...

#Liunx内存管理# 在32bit Linux内核中,用户空间和内核空间的比例通常是3:1,可以修改成2:2吗?

在32位Linux内核中&#xff0c;用户空间和内核空间的3:1默认比例可以修改为2:2&#xff0c;但需要权衡实际需求和潜在影响。以下是具体分析&#xff1a; 一、修改可行性 1.技术实现 通过内核启动参数调整虚拟地址空间划分&#xff0c;例如在GRUB配置中添加mem2G参数&#xff0c…...

经济统计常见的同比与环比是啥意思?同比和环比有什么区别?

在经济统计领域&#xff0c;其实大家都会经常性看到同比还有环比&#xff0c;可人们对此就会觉得有些疑惑。到底是什么意思&#xff1f;这两者之间又有什么样的区别呢&#xff1f;下面就为大家来详细的介绍一下。 同比与环比是用于衡量数据变化趋势的关键指标&#xff0c;可以给…...

前端知识点---本地存储(javascript)

localStorage 是浏览器提供的一个 本地存储 API&#xff0c;可以在用户的浏览器中存储数据&#xff0c;数据不会随页面刷新而丢失。 1. 基本用法 (1) 存储数据&#xff08;setItem&#xff09; localStorage.setItem("username", "zhangsan");存储 “use…...

压测工具开发实战篇(二)——构建侧边栏以及设置图标字体

你好&#xff0c;我是安然无虞。 文章目录 构建侧边栏QtAwesome使用调整侧边栏宽度了解: sizePolicy属性伪状态 在阅读本文之前, 有需要的老铁可以先回顾一下上篇文章: 压测工具开发(一)——使用Qt Designer构建简单界面 构建侧边栏 我们要实现类似于下面这样的侧边栏功能: …...

【Java Stream详解】

文章目录 前言一、Stream概述1.1 什么是 Stream&#xff1f;1.2 Stream 和集合的区别 二、Stream的创建方式2.1 基于集合创建2.2 基于数组创建2.3 使用 Stream.generate()2.4 使用 Stream.iterate() 三、Stream常见操作3.1 中间操作&#xff08;Intermediate&#xff09;① fil…...

16进制在蓝牙传输中的应用

在蓝牙传输中&#xff0c;16进制&#xff08;Hexadecimal&#xff09;是一种常用的数据表示方法。它主要用于描述数据包的内容、地址、命令、参数等信息。以下是16进制在蓝牙传输中的具体应用场景和作用&#xff1a; 1. 数据包的表示 蓝牙通信中&#xff0c;所有数据最终都以二…...

TypeConverter

文章目录 基本描述主要功能接口源码主要实现最佳实践与其他组件的关系常见问题 基本描述 TypeConverter接口是Spring框架中用于在SpEL&#xff08;Spring表达式语言&#xff09;中进行类型转换的核心接口&#xff0c;它允许将不同类型的对象相互转换&#xff0c;例如将字符串转…...

优化 Web 性能:压缩 CSS 文件(Unminified CSS)

在 Web 开发中&#xff0c;CSS 文件的大小直接影响页面加载速度和用户体验。Google 的 Lighthouse 工具在性能审计中特别关注“未压缩的 CSS 文件”&#xff08;Unminified CSS&#xff09;&#xff0c;指出未经过压缩的样式表会增加不必要的字节&#xff0c;拖慢页面渲染。本文…...

每日一个小病毒(C++)EnumChildWindows+shellcode

这里写目录标题 1. `EnumChildWindows` 的基本用法2. 如何利用 `EnumChildWindows` 执行 Shellcode?关键点:完整 Shellcode 执行示例3. 为什么 `EnumChildWindows` 能执行 Shellcode?4. 防御方法5. 总结EnumChildWindows 是 Windows API 中的一个函数,通常用于枚举所有子窗…...

leetcode数组-移除元素

题目 题目链接&#xff1a;https://leetcode.cn/problems/remove-element/ 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。 假设 nums 中不等于 val 的元素数量为…...

Git 教程:从 0 到 1 全面指南 教程【全文三万字保姆级详细讲解】

目录 什么是 Git &#xff1f; Git 与 SVN 区别 Git 安装配置 Linux 平台上安装 Centos/RedHat 源码安装 Windows 平台上安装 使用 winget 工具 Mac 平台上安装 Git 配置 用户信息 文本编辑器 差异分析工具 查看配置信息 生成 SSH 密钥&#xff08;可选&#xf…...

在 Android Studio 中运行安卓应用到 MuMu 模拟器

一、准备工作 1、​​确保 MuMu 模拟器已正确安装并启动​​ 从官网下载安装最新版 MuMu 模拟器。启动后&#xff0c;建议在设置中调整性能参数&#xff08;如 CPU 核心数和内存分配&#xff09;&#xff0c;以保证流畅运行。 2、​​配置 Android Studio 环境​&#xff08;按…...

stable diffusion部署ubuntu

stable-diffusion webui: https://github.com/AUTOMATIC1111/stable-diffusion-webui python3.10 -m venv venv&#xff08;3.11的下torch会慢得要死&#xff09; source venv/bin/activate 下载checkpoint模型放入clip_version"/home/chen/软件/stable-diffusion-webu…...

《概率论与数理统计》期末复习笔记_下

目录 第4章 随机变量的数字特征 4.1 数学期望 4.2 方差 4.3 常见分布的期望与方差 4.4 协方差与相关系教 第5章 大数定律和中心极限定理 5.1 大数定律 5.2 中心极限定理 第6章 样本与抽样分布 6.1 数理统汁的基本概念 6.2 抽样分布 6.2.1 卡方分布 6.2.2 t分布 6.…...

Java异步编程实战:线框-管道模型的设计与实现

一、什么是线框-管道模型&#xff1f; 线框-管道模型&#xff08;Pipeline-Filter Pattern&#xff09;是一种经典的数据处理架构&#xff0c;其核心思想是将复杂任务拆分为多个独立的处理阶段&#xff08;Filter&#xff09;&#xff0c;通过管道&#xff08;Pipe&#xff09…...

Linux make与makefile 项目自动化构建工具

本文章将对make与makefile进行一些基础的讲解。 假设我们要建造一座房子&#xff0c;建造过程涉及很多步骤&#xff0c;比如打地基、砌墙、安装门窗、粉刷墙壁等。每个步骤都有先后顺序&#xff0c;并且有些步骤可能依赖于其他步骤的完成。比如&#xff0c;你必须先打好地基才…...

鸿蒙 harmonyOS 网络请求

应用通过HTTP发起一个数据请求&#xff0c;支持常见的GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE、CONNECT方法。 接口说明 HTTP数据请求功能主要由http模块提供。 使用该功能需要申请ohos.permission.INTERNET权限。 第一步 &#xff1a; 在module.json5文件里面添加网络…...

【Tauri2】014——简单使用listen和emit

前言 【Tauri2】013——前端Window Event与创建Window-CSDN博客https://blog.csdn.net/qq_63401240/article/details/146981362?spm1001.2014.3001.5502【Tauri2】012——on_window_event函数-CSDN博客https://blog.csdn.net/qq_63401240/article/details/146909801?spm1001…...

解锁 C 语言安全新姿势:C11 安全函数全解析

一、开篇&#xff1a;C 语言安全的新护盾 在 C 语言的编程世界里&#xff0c;缓冲区溢出等安全问题犹如潜藏的暗礁&#xff0c;时刻威胁着程序的稳定与安全。为了有效应对这些挑战&#xff0c;C11 标准引入了一系列安全函数&#xff0c;也被称为 “Annex K” 标准库函数。这些…...

【centos】经常使用的脚本

磁盘挂载 yum install wget -y && wget -O auto_disk.sh http://download.bt.cn/tools/auto_disk.sh && bash auto_disk.shYum镜像源更换 bash <(curl -sSL https://linuxmirrors.cn/main.sh)Yum切换安装的java版本 sudo alternatives --config java...

Unity URP渲染管线详解

一、URP概述 Universal Render Pipeline (URP&#xff0c;通用渲染管线)是Unity推出的轻量级、高性能渲染管线解决方案&#xff0c;适用于移动平台、PC和主机等多种平台。 URP核心特点 跨平台支持&#xff1a;针对不同硬件自动优化 模块化设计&#xff1a;可扩展的渲染功能 …...

Python语言的测试用例设计

Python语言的测试用例设计 引言 随着软件开发的不断进步&#xff0c;测试在软件开发生命周期中的重要性日益凸显。测试用例设计是软件测试的核心&#xff0c;它为软件系统的验证和验证提供了实施的基础。在Python语言中&#xff0c;由于其简洁明了的语法和强大的内置库&#…...

【记录】kali制作绕过火绒检测的木马(仅通过MSF的方式)

目的&#xff1a;制作一个能够绕过火绒检测的简单木马&#xff0c;熟悉一下怎么使用msfvenom制作木马&#xff0c;因此此处使用的火绒版本较低。 工具准备&#xff1a;火绒安全-3.0.42.0 【点击免费下载工具】 **实验环境&#xff1a;**kali-2019.4 &#xff08;攻击方&…...

Linux系统进程

Linux系统进程 程序开始 编译链接的引导代码 操作系统下的应用程序在main执行前也需要先执行段引导代码才能去执行main&#xff0c;但写应用程序时不用考虑引导代码的问题&#xff0c;编译连接时&#xff08;准确说是链接时&#xff09;由链接器将编译器中事先准备好的引导代码…...

Obsidian按下三个横线不能出现文档属性

解决方案: 需要在标题下方的一行, 按下 键盘数字0后面那个横线(英文横线), 然后回车就可以了 然后点击横线即可...

GitHub 上开源一个小项目的完整指南

GitHub 上开源一个小项目的完整指南 &#x1f680; 第一步&#xff1a;准备你的项目 在开源之前&#xff0c;确保项目是可用且有一定结构的&#xff1a; ✅ 最低要求 项目文件清晰、结构合理&#xff08;比如&#xff1a;src/、README.md、LICENSE&#xff09;项目能在本地正…...

大模型——MCP 集成至 LlamaIndex 的技术实践

MCP 集成至 LlamaIndex 的技术实践 一、前言 本文主要介绍了如何将 MCP(Model Context Protocol,模型上下文协议)工具转换为可以直接使用的 LlamaIndex 工具,使 LlamaIndex 用户能像使用 Claude, Cursor 等现代 AI 应用一样无缝集成这些服务。 二、技术背景 2.1 什么是…...

leetcode 1123. 最深叶节点的最近公共祖先

给你一个有根节点 root 的二叉树&#xff0c;返回它 最深的叶节点的最近公共祖先 。 回想一下&#xff1a; 叶节点 是二叉树中没有子节点的节点树的根节点的 深度 为 0&#xff0c;如果某一节点的深度为 d&#xff0c;那它的子节点的深度就是 d1如果我们假定 A 是一组节点 S …...

LeetCode热题100记录-【链表】

链表 160.相交链表 思考&#xff1a;只要p1和p2不相等就一直在循环里&#xff0c;因为就算都为null也会走到相等 记录&#xff1a;需要二刷 public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {ListNode p1 headA,p2 headB;whi…...

Python 布尔类型

Python 布尔类型(Boolean) 布尔类型是Python中的基本数据类型之一&#xff0c;用于表示逻辑值。它只有两个值&#xff1a; True - 表示真False - 表示假 1. 布尔值的基本使用 # 定义布尔变量 is_active True is_admin Falseprint(is_active) # 输出: True print(is_admi…...

恒盾C#混淆加密卫士 - 混淆加密保护C#程序

对于大部分C#开发者来说&#xff0c;写完代码点个发布就完事儿了&#xff0c;但你可能不知道——用记事本都能扒开你编译好的程序&#xff01;像dnSpy这类反编译工具&#xff0c;分分钟能把你的EXE/DLL变回原汁原味的源代码&#xff0c;商业机密赤裸裸曝光不说&#xff0c;竞争…...

Java基础 4.4

1.方法快速入门 public class Method01 {//编写一个main方法public static void main(String[] args) {//方法使用//1.方法写好后&#xff0c;如果不去调用(使用)&#xff0c;不会输出Person p1 new Person();p1.speak();//调用方法 p1.cal01();//调用计算方法1p1.cal02(10);…...

黑马点评redis改 part 1

本篇将主要阐述短信登录的相关知识&#xff0c;感谢黑马程序员开源&#xff0c;感谢提供初始源文件&#xff08;给到的是实战第7集开始的代码&#xff09;【Redis实战篇】黑马点评学习笔记&#xff08;16万字超详细、Redis实战项目学习必看、欢迎点赞⭐收藏&#xff09;-CSDN博…...

降维算法之t-SNE

t-SNE&#xff08;t-Distributed Stochastic Neighbor Embedding&#xff09;算法详解 先说理解&#xff1a; t-SNE&#xff08;t-distributed Stochastic Neighbor Embedding&#xff09;是一种用来“可视化高维数据”的降维方法&#xff0c;通俗来说&#xff0c;它就像一个…...

使用 .NET 9 和 Azure 构建云原生应用程序:有什么新功能?

随着 .NET 9 推出一系列以云为中心的增强功能&#xff0c;开发人员拥有比以往更多的工具来在 Azure 上创建可扩展、高性能的云原生应用程序。让我们深入了解 .NET 9 中的一些出色功能&#xff0c;这些功能使构建、部署和优化云应用程序变得更加容易&#xff0c;并附有示例以帮助…...

python基础-10-组织文件

文章目录 【README】【10】组织文件&#xff08;复制移动删除重命名&#xff09;【10.1】shutil模块(shell工具)【10.1.1】复制文件和文件夹【10.1.1.1】复制文件夹及其下文件-shutil.copytree 【10.1.2】文件和文件夹的移动与重命名【10.1.3】永久删除文件和文件夹【10.1.4】用…...

从代码学习深度学习 - LSTM PyTorch版

文章目录 前言一、数据加载与预处理1.1 代码实现1.2 功能解析二、LSTM介绍2.1 LSTM原理2.2 模型定义代码解析三、训练与预测3.1 训练逻辑代码解析3.2 可视化工具功能解析功能结果总结前言 深度学习中的循环神经网络(RNN)及其变种长短期记忆网络(LSTM)在处理序列数据(如文…...

linux gcc

一、常用编译选项 ​基本编译 gcc [input].c -o [output] ​示例&#xff1a; gcc hello.c -o hello # 将 hello.c 编译为可执行文件 hello ./hello # 运行程序 ​分步编译 预处理&#xff1a;-E&#xff08;生成 .i 文件&#xff09; gcc -E hello.c -o hello…...