深度解析算法之二分查找(2)
17.二分查找
题目链接
给定一个 n
个元素有序的(升序)整型数组 nums
和一个目标值 target
,写一个函数搜索 nums
中的 target
,如果目标值存在返回下标,否则返回 -1
。
示例 1:
输入: nums
= [-1,0,3,5,9,12], target
= 9
输出: 4
解释: 9 出现在 nums
中并且下标为 4
示例 2:
输入: nums
= [-1,0,3,5,9,12], target
= 2
输出: -1
解释: 2 不存在 nums
中因此返回 -1
暴力解法就是遍历这个数组,找到这个元素就将这个元素的下标进行返回
时间内复杂度的话就是O(N)的
我们找到一个数4,我们现在要找target=5,那么4比5小,那么4左边的数字肯定都比5小,那么4左边的数字我们就不需要去看了
那么我们直接将4左边的区间干掉,从4右边的区间去找
所以我们的思路就是,在一个数组中随便找一个点,将这个数和target进行比较,如果这个数小于tartget的话,那么我们直接从这个数的右边的区间去找,如果这个数比target大的话,那么我们从这个数的左边去找
只要数组有二段性的话,那么我们就可以使用二分查找算法
我们可以找二分之一的位置,或者三分之一的位置的数,只要能将我们的数组分成两段的话,都是可行的,但是的话我们选择我们中间的点的效果是最好的
因为我们的二分查找的算法是从中间的点去选择是最好的
我们需要频繁的找中点和频繁的找区间,所以我们是需要定义三个指针,一个left指向我们数组开始的数,一个right指向我们最后一个数字,一个mid指向中间的元素,根据中间点的值和target进行比较然后确定我们的区间
如果我们的mid<target的话,那么我们的left直接定义到mid+1的位置,我们再从[mid+1,right]这个区间找中间值去分区间,所以我们二分查找算法是循环式的
如果我们的mid>target的话,那么我们的right就需要定义到mid-1的位置,那么我们就需要从[left,mid-1]的位置开始,
还有一种运气爆棚的情况,就是我们的mid=target,那么我们就直接找到了目标 值
细节问题
1.循环结束的条件
当left>right,我们就停止循环
2.时间复杂度。
时间复杂度是logn
class Solution {public:int search(vector<int>& nums, int target){int left=0,right=nums.size()-1;while(left<right){//int mid=(left+right)/2;//这种求中间值的方法存在溢出的现象int mid= left+(right-left)/2;//这种方式是可以算出中间点的,总长度/2,然后让left加上去,那么就得到了我们中间点了,还能防止溢出的//分三种情况进行讨论if(nums[mid]<target){left=mid+1;}else if(nums[mid]>target){right=mid-1;}else return mid;//正好找到了结果}//整个while循环结束了都没找到的话,那么我们直接返回-1就行了return -1;}};
我们这里求中间值的代码是left+(right-left)/2
因为这样可以避免溢出的情况出现
朴素二分查找模版如下:
根据题目的要求往里面填东西
18.在排序数组中查找元素的第一个和最后一个位置
题目链接
给你一个按照非递减顺序排列的整数数组 nums
,和一个目标值 target
。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target
,返回 [-1, -1]
。
你必须设计并实现时间复杂度为 O(log n)
的算法解决此问题。
示例 1:
输入: nums = [5,7,7,8,8,10]
, target = 8
输出:[3,4]
示例 2:
输入: nums = [5,7,7,8,8,10]
, target = 6
输出:[-1,-1]
示例 3:
输入: nums = [], target = 0
输出:[-1,-1]
给到我们的数组要么是递增的,要么是不变的
暴力解法就是从开始到末尾,最差的情况下时间复杂度是O(N)
朴素二分的话,虽然可以实现这个题,但是时间复杂度不行、
我们这里的话,当x小于t的话,处理方式和我们朴素二分的方式一样的
查找区间的左端点
但是当我们的x>=t的话,我们需要将我们的right定位到我们的mid的位置上,因为mid可能是左端点的位置,如果我们将right定位到mid-1的话,恰好此时Mid就是我们要找的话,那么就永远找不到t了
细节处理:
循环条件
循环条件必须是left<right,不能是left<=right
一是因为当left=right的时候就是最终的结果
而是因为我们判断了的话就会陷入死循环了
如果我们此时left=right的话,我们进入到上面的第二个条件了
right=mid,那么此时right就会原地不动进行死循环了
现在我们的求中点的话有两种方式
left+(right-left)/2
==left+(right-left+1)/2
当我们数组元素是偶数的时候的话,我们使用第一种的话,那么我们的中点是相较于靠左的
,第二种方法的话就是靠右的
当我们使用第二种求中点的方式后,当我们数组中只剩下两个数之后,我们的right在后续判断中是会陷入死循环的
所以我们只能使用我们第一种求中点的方法,
查找区间的右端点
当x<=t的时候,我们的更新策略是left=mid
当x>t,right=mid-1
我们循环条件必须是left<right ,求中点的方式,因为我们这里是求右端点
所以我们求中点的方式是left+(right-left+1)/2
解决代码
class Solution {public:vector<int> searchRange(vector<int>& nums, int target){//处理数组为空的情况if(nums.size()==0) return {-1,-1};int begin=0;//二分左端点int left=0,right=nums.size()-1;while(left<right){int mid=left+(right-left)/2;if(nums[mid]<target) left=mid+1;else right=mid;}//此时left和mid的在循环结束就相遇了//判断是否存在结果if(nums[left]!=target) return {-1,-1};else begin=left;//2.二分右端点right=nums.size()-1;//这里我们重置下右端点就行了,左端点的话不需要动while(left<right){int mid=left+(right-left+1)/2;if(nums[mid]<=target) left=mid;else right=mid-1;}//那么出了循环了,此时的两个指针都指向我们的右端点了,那么我们下面直接返回就行了return {begin,right};}};
我们使用两个二分查找来找出我们符合条件的区间
我们先使用二分查找找到我们的左端点,在这个二分中,为了找到我们的左端点,我们的求中点的方式一定要设置为left+(right-left)/2,这样的话当我们数组是偶数元素的话,那么我们的mid是会落在左边的,在循环结束之后,我们使用begin记录我们的左端点的位置
在第二个二分中,我们去求我们的右端点,
寻找左边界:
- 我们注意到以左边界划分的两个区间的特点:
左边区间 [left, resLeft - 1] 都是⼩于 x 的;
右边区间(包括左边界) [resLeft, right] 都是⼤于等于 x 的; - 因此,关于 mid 的落点,我们可以分为下⾯两种情况:
当我们的 mid 落在 [left, resLeft - 1] 区间的时候,也就是 arr[mid] <target 。说明 [left, mid] 都是可以舍去的,此时更新 left 到 mid + 1 的位置,继续在 [mid + 1, right] 上寻找左边界;
当 mid 落在 [resLeft, right] 的区间的时候,也就是 arr[mid] >= target 。说明 [mid + 1, right] (因为 mid 可能是最终结果,不能舍去)是可以舍去的,此时更新 right 到 mid 的位置,继续在 [left, mid] 上寻找左边界;
寻右左边界:
- ⽤ resRight 表⽰右边界;
我们注意到右边界的特点:左边区间 (包括右边界) [left, resRight] 都是⼩于等于 x 的;右边区间 [resRight+ 1, right] 都是⼤于 x 的; - 因此,关于 mid 的落点,我们可以分为下⾯两种情况:当我们的 mid 落在 [left, resRight] 区间的时候,说明 [left, mid - 1]( mid 不可以舍去,因为有可能是最终结果) 都是可以舍去的,此时更新 left 到 mid,当 mid 落在 [resRight+ 1, right] 的区间的时候,说明 [mid, right] 内的元素是可以舍去的,此时更新 right 到 mid - 1 的位置;
左指针: left = mid ,可能会原地踏步(⽐如:如果向下取整的话,如果剩下 1,2 两个元素, left == 1, right == 2,mid == 1 。更新区间之后, left,right,mid 的值没有改变,就会陷⼊死循环)。
右指针: right = mid - 1 ,是会向前移动的,因此区间是会缩⼩的;因此⼀定要注意,当 right = mid 的时候,要向下取整。
总结二分模版
19.x 的平方根
题目链接
给你一个非负整数 x
,计算并返回 x
的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意: 不允许使用任何内置指数函数和算符,例如 pow(x, 0.5)
或者 x ** 0.5
。
示例 1:
输入: x = 4
输出: 2
示例 2:
输入: x = 8
输出: 2
解释: 8 的算术平方根是 2.82842…, 由于返回类型是整数,小数部分将被舍去。
0 <= x <= 231 - 1
我们可以直接利用二分查找进行操作
class Solution {public:int mySqrt(int x){if(x<1) return 0;//处理边界情况int left=1,right=x;while(left<right){//一段区级上,如果我们的mid*mid<=x的话,那么目标肯定在mid右边,甚至可能是mid,我们让left=mid//如果mid*mid<x的话,那么肯定是在mid左边,我们直接让right=mid-1就行了long long mid=left+(right-left+1)/2;// long long 防溢出if(mid*mid<=x) left=mid;else right=mid-1;}//出了循环之后,我们的midreturn left;}};
20.搜索插入位置
题目链接
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n)
的算法。
示例 1:
输入: nums = [1,3,5,6], target = 5
输出: 2
示例 2:
输入: nums = [1,3,5,6], target = 2
输出: 1
示例 3:
输入: nums = [1,3,5,6], target = 7
输出: 4
如果我们在一段数组中找到了target的话,那么我们就返回他的对应下标
如果没有找到的话,那么就返回我们该插入的位置的下标
我们这里的target在数组中找不到,然后我们需要找到他插入的位置,
我们将这个数组分成两个区间,左边的就是小于t的,右边的就是大于等于t的
那么我们仅仅需要找到大于等于这段区域的左端点就行了,所以现在我们使用查找区间左端点的模版来进行操作
如果 x<t 的话,x落在了左边区间里面了,那么结果一定不会在这里的,所以我们是需要让left更新为mid+1,然后在右边的这段区间继续寻找结果
就是left=mid+1
如果x>=t的话,那么我们就是掉在了第二块区间里面了,我们需要去这段区间的左半边去寻找结果,因为此时的mid可能是最终的结果,所有我们直接让right=mid
class Solution {public:int searchInsert(vector<int>& nums, int target){int left=0,right=nums.size()-1;while(left<right){int mid=left+(right-left)/2;if(nums[mid]<target) left=mid+1;else right=mid;}if(nums[left]<target) return left+1;//就是在末尾了,此时的left,那么我们直接将target插入到left+1的位置了return left;}};
21.山脉数组的峰顶索引
题目链接
给定一个长度为 n
的整数 山脉 数组 arr
,其中的值递增到一个 峰值元素 然后递减。
返回峰值元素的下标。
你必须设计并实现时间复杂度为 O(log(n))
的解决方案。
示例 1:
输入: arr = [0,1,0]
输出: 1
示例 2:
输入: arr = [0,2,1,0]
输出: 1
示例 3:
输入: arr = [0,10,5,2]
输出: 1
这个山峰数组就是先上升后下降,这个题就是让我们找到我们的封顶元素,然后返回对应数据的下标
当我们在遍历的时候, 第一次遇到一个数大于后面的数的话,那么这个数就是峰值,当我们第一次扫描到这个数的时候我们就停止下来
所以我们的解法一:利用暴力枚举,时间复杂度是O(N)
我们将整个数组分成两个部分
arr[i]>arr[i-1] 和 arr[i]<arr[i-1]
那么这里就可以看出二段性了
如果落在了左边的区间的话,那么我们的mid包含最终的结果
arr[mid]>arr[mid-1],我们这里更新lefy=mid (mid可能是最终的结果)
落在右边的区间的话,那么这段区域一定不是最终的结果,那么我们直接都忽略掉
arr[mid]<arr[mid-1],我们这里更新right=mid-1
那么我们取中间值的话,我们就是left+(right-left+1)/2
class Solution {public:int peakIndexInMountainArray(vector<int>& arr){int left=1,right=arr.size()-2; //因为我们第一个元素和最后一个元素绝对不可能是最终的结果,所以我们就这么设置 while(left<right){int mid=left+(right-left+1)/2;if(arr[mid]>arr[mid-1])left=mid;else right=mid-1;}//二分结束了,那么我们返回这个结果就行了return left;}};
22.寻找峰值
题目链接
峰值元素是指其值严格大于左右相邻值的元素。
给你一个整数数组 nums
,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。
你可以假设 nums[-1] = nums[n] = -∞
。
你必须实现时间复杂度为 O(log n)
的算法来解决此问题。
示例 1:
输入: nums = [1,2,3,1]
输出: 2
解释: 3 是峰值元素,你的函数应该返回其索引 2。
示例 2:
输入: nums = [
1,2,1,3,5,6,4]
输出: 1 或 5
解释: 你的函数可以返回索引 1,其峰值元素为 2;
或者返回索引 5, 其峰值元素为 6。
提示:
1 <= nums.length <= 1000
-231 <= nums[i] <= 231 - 1
- 对于所有有效的
i
都有nums[i] != nums[i + 1]
如果第一个值就是-∞,那么我们直接返回0就行了
暴力解法就是从第一个位置开始走,一直向后走,分情况讨论即可
现在将整个数组分成两个部分,我们数组开始和结束的位置都是-∞
如果我们的arr[i]>arr[i+1]的话,那么就说明我们左边区域肯定是存在峰值的,因为从-∞开始的话,我们是上升的,可能是一直上升到i的位置,所以这种情况的话左边是存在峰值的,右边的话可能存在峰值
如果是arr[i]<arr[i+1]的话,那么我们左边的话可能不存在峰值,右边区域可能存在峰值了
我们这道题的话是存在二段性的
如果arr[mid]>arr[mid+1]的话,说明我们左边的这段区域是一定会有结果的,包含mid,所以我们直接让right=mid
如果是arr[i]<arr[i+1]的话,说明我们友区间是一定存在结果的,所有我们让left=mid+1即可
class Solution {public:int findPeakElement(vector<int>& nums){int left=0,right=nums.size()-1;while(left<right){int mid=left+(right-left)/2;if(nums[mid]>nums[mid+1]) right=mid;else left=mid+1;}return left;}};
23.寻找旋转排序数组中的最小值
题目链接
已知一个长度为 n
的数组,预先按照升序排列,经由 1
到 n
次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7]
在变化后可能得到:
- 若旋转
4
次,则可以得到[4,5,6,7,0,1,2]
- 若旋转
7
次,则可以得到[0,1,2,4,5,6,7]
注意,数组 [a[0], a[1], a[2], ..., a[n-1]]
旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]]
。
给你一个元素值 互不相同 的数组 nums
,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。
你必须设计一个时间复杂度为 O(log n)
的算法解决此问题。
示例 1:
输入: nums = [3,4,5,1,2]
输出: 1
解释: 原数组为 [1,2,3,4,5] ,旋转 3 次得到输入数组。
示例 2:
输入: nums = [4,5,6,7,0,1,2]
输出: 0
解释: 原数组为 [0,1,2,4,5,6,7] ,旋转 4 次得到输入数组。
示例 3:
输入: nums = [11,13,15,17]
输出: 11
解释: 原数组为 [11,13,15,17] ,旋转 4 次得到输入数组。
以这个为例子[0,1,2,4,5,6,7],旋转一次就是将7挪动到前面了,旋转2次就是将6挪动到前面了
解法一:暴力查找最小值,时间复杂度就是O(N)
AB这一段是大于D点的值的,CD这一段是小于等于D点的值的
A~B:nums[i]>nums[n-1]
C~D:nums[i]<=nums[n-1]
如果落在AB区间的话,那么nums[mid]>nums[n-1]
- 如果中间元素大于右边的元素,则最小值在右半部分。
- 如果中间元素小于或等于右边元素,则最小值在左半部分或可能是中间元素本身。
不断地利用中间值和right对应的值进行比较,,因为这个数组在转的时候,第一次是最后一个最大的数字到前面,第二次是最后一个第二大的数字到前面
如果我们中间元素大于右边的元素的话,那么最小值肯定是出现在在右边的,左边的就是比较大的数字的,那么我们是需要找到最小值的,所以我们需要往右边靠的,因为中间元素大于右边的元素,所以我们直接让left=mid+1
但是如果mid位置的值小于等于最右边的值的话,那么最小值肯定在左边,甚至可能是mid的位置,所以我们让right=mid
class Solution {public:int findMin(vector<int>& nums){int left=0,right=nums.size()-1;while(left<right) {int mid=left+(right-left)/2;if(nums[mid]>nums[right]) left=mid+1;else right=mid;}//此时我们的left和right相遇的就是最小的元素return nums[left];}};
24.缺失的第一个正整数
题目链接
一个长度为 n−1n−1 的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围 00 到 n−1n−1 之内。
在范围 00 到 n−1n−1 的 nn 个数字中有且只有一个数字不在该数组中,请找出这个数字。
数据范围
1≤n≤10001≤n≤1000
样例
输入:[0,1,2,4]输出:3
可以利用下面的方法进行求出这个缺失的数,第四种就是利用等差数列求和求出数组总大小,然后依次减去数组中的每个数,最后剩下的就是我们缺失的数
我们可以将数组分成两个部分,左边的就是数组和下标相等的,右边的数的大小比下标大1的,所以我们需要找到我们右边这段区间最左边的这个数的下标就可以知道我们缺失的那个数是什么了
当我们的mid落在左边区域的话,那么我们是需要去右边去寻找的,所以我们需要更新left=mid+1,这段区间的判断条件是nums [mid]=mid
如果落在右边区域的话,那么我们需要往左边靠,找到这个区间的靠左的数,我们需要更新right=mid,mid有可能在最终结果上,
右边区间的判断条件是nums[mid]!=mid
但是存在一种边界的情况。下面的话就是我们缺少了4,但是循环结束后我们最终会落在3这个位置上面的,我们需要的结果是3这个位置后面的一位数
所以我们返回结果的时候需要进行判断下,我们结束的位置的nums[mid]=mid,说明我们此时的数组是一个完全递增的数组,我们缺失的数就是mid+1
class Solution {
public:int getMissingNumber(vector<int>& nums){int left=0,right=nums.size()-1;while(left<right){int mid=left+(right-left)/2;if(nums[mid]==mid) left=mid+1;//落在左边的区间中else right=mid;}//处理下细节问题return nums[left]==left?left+1:left;//如果等于left的话就返回left+1,如果不等于的话就返回left}
};
相关文章:
深度解析算法之二分查找(2)
17.二分查找 题目链接 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。 示例 1: 输入: nums [-1,0,3,5,9,12], target…...
前端工程化之自动化测试
自动化测试 自动化测试为什么需要测试?什么时候需要考虑测试测试类型前端测试框架单元测试Jest 重点掌握项目示例package.jsonsrc/utils/math.tssrc/utils/math.test.ts进行测试jest.config.js覆盖率直观看覆盖率coverage/lcov-report/index.html src/main.test.tst…...
CANFD技术在新能源汽车通信网络中的应用与可靠性分析
一、引言 新能源汽车产业正处于快速发展阶段,其电子系统复杂度不断攀升,涵盖众多传感器、控制器与执行器。高效通信网络成为确保新能源汽车安全运行与智能功能实现的核心要素。传统CAN总线因带宽限制,难以满足高级驾驶辅助系统(A…...
【机器学习】朴素贝叶斯算法:原理剖析与实战应用
引言 朴素贝叶斯算法就像是一位善于从经验中学习的侦探,根据已有的线索来推断未知事件的概率。这是一种基于概率论的分类算法,以贝叶斯定理为基础,却做了一个"朴素"的假设:认为所有特征彼此独立。虽然这个假设在现实中…...
【更新完毕】2025妈妈杯C题 mathercup数学建模挑战赛C题数学建模思路代码文章教学:音频文件的高质量读写与去噪优化
完整内容请看文章最下面的推广群 我将先给出文章、代码、结果的完整展示, 再给出四个问题详细的模型 面向音频质量优化与存储效率提升的自适应编码与去噪模型研究 摘 要 随着数字媒体技术的迅速发展,音频处理技术在信息时代的应用愈加广泛,特别是在存储…...
UI键盘操作
1、Selenium中send_keys除了可以模拟键盘输入之外,还有些时候需要操作键盘上的按键,甚至是组合键,比如CTRLA,CTRLC等, 所以我们需要代码操作键盘。使用的是send_keys里的Keys的类。 from selenium.webdriver.common.keys import …...
【正则表达式】正则表达式使用总结
正则表达式除了匹配普通字符外,还可以匹配特殊字符,这些特殊字符被称为“元字符”。 特殊字符(元字符) 限定符:用于指定正则表达式中某个组件的出现次数。常见的限定符包括: *:0次或多次 +:1次或多次 ?:0次或1次 {n}:恰好n次…...
Qt编写推流程序/支持webrtc265/从此不用再转码/打开新世界的大门
一、前言 在推流领域,尤其是监控行业,现在主流设备基本上都是265格式的视频流,想要在网页上直接显示监控流,之前的方案是,要么转成hls,要么魔改支持265格式的flv,要么265转成264,如…...
Spring Boot 中基于 Reactor 的服务器端事件(SSE)推送机制实践
Spring Boot 3.0 中基于 Reactor 的服务器端事件(SSE)推送机制实践 在现代 Web 应用开发中,实时数据交互越来越成为刚需,从股票行情的实时更新到社交平台的消息即时推送,服务器端事件(Server-Sent Events,简称 SSE)作为一种高效的单向数据传输技术,正发挥着重要作用。…...
CRC实战宝典:从原理到代码,全面攻克循环冗余校验
CRC实战宝典:从原理到代码,全面攻克循环冗余校验 github开源:CRC软硬件协同测试项目 CRC 简介 CRC(循环冗余校验)是一种强大的错误检测技术,广泛应用于数字网络和存储系统。它是确保数据完整性的重要方法…...
【愚公系列】《Python网络爬虫从入门到精通》056-Scrapy_Redis分布式爬虫(Scrapy-Redis 模块)
🌟【技术大咖愚公搬代码:全栈专家的成长之路,你关注的宝藏博主在这里!】🌟 📣开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主! …...
ZLMediaKit 和 SRS的区别,哪个更好用?
ZLMediaKit 和 SRS(Simple RTMP Server)是两个主流的开源流媒体服务器框架,各自在功能、性能、适用场景等方面存在显著差异。以下是两者的对比分析及选择建议: 一、核心差异对比 协议支持 ZLMediaKit:支持更广泛的流媒…...
【PyTorch】colab上跑VGG(深度学习)数据集是 CIFAR10
跑得结果是测试准确率10%,欠拟合。 import torch import torchvision.datasets from torch import nn from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriter from torchvision import datasets, transformstransform tran…...
pytorch 51 GroundingDINO模型导出tensorrt并使用c++进行部署,53ms一张图
本专栏博客第49篇文章分享了将 GroundingDINO模型导出onnx并使用c++进行部署,并尝试将onnx模型转换为trt模型,fp16进行推理,可以发现推理速度提升了一倍。为此对GroundingDINO的trt推理进行调研,发现 在GroundingDINO-TensorRT-and-ONNX-Inference项目中分享了模型导出onnx…...
编程语言基础 - C++ 面试题
C++ 面试题 tags: c++ 文章目录 C++ 面试题关键字1. const2. static3. this 指针4. inline 内联函数5. volatile6. struct, class7. enum关键字 1. const 修饰变量:该变量不能被改变 修饰指针: 指针常量: 指针本身是常量 TYPE* const pContent;指向常量的指针:指针所指向…...
JVM笔记【一】java和Tomcat类加载机制
JVM笔记一java和Tomcat类加载机制 java和Tomcat类加载机制 Java类加载 * loadClass加载步骤类加载机制类加载器初始化过程双亲委派机制全盘负责委托机制类关系图自定义类加载器打破双亲委派机制 Tomcat类加载器 * 为了解决以上问题,tomcat是如何实现类加载机制的…...
Python----深度学习(全连接与链式求导法则)
一、机器学习和深度学习的区别 机器学习:利用计算机、概率论、统计学等知识,输入数据,让计算机学会新知 识。机器学习的过程,就是训练数据去优化目标函数。 深度学习:是一种特殊的机器学习,具有强大的能力和…...
基于SpringBoot的网上找律师管理系统
博主介绍:java高级开发,从事互联网行业六年,熟悉各种主流语言,精通java、python、php、爬虫、web开发,已经做了六年的毕业设计程序开发,开发过上千套毕业设计程序,没有什么华丽的语言࿰…...
《目标检测双雄:YOLO与Faster R-CNN,谁主沉浮?》
在计算机视觉的广阔天地里,目标检测技术宛如一颗璀璨的明星,照亮了无数应用场景。从安防监控中对行人与车辆的精准识别,到自动驾驶领域对道路障碍物的快速判断,再到工业生产里对产品缺陷的严格检测,目标检测无处不在&a…...
CUDA编程中影响性能的小细节总结
一、内存访问优化 合并内存访问:确保相邻线程访问连续内存地址(全局内存对齐访问)。优先使用共享内存(Shared Memory)减少全局内存访问。避免共享内存的Bank Conflict(例如,使用padding或调整访…...
C#学习第17天:序列化和反序列化
什么是序列化? 定义:序列化是指把对象转换为一种可以轻松存储或传输的格式,如JSON、XML或二进制格式。这个过程需要捕获对象的类型信息和数据内容。用途:使得对象可以持久化到文件、发送至网络、或存储在数据库中。 什么是反序列…...
kafka的零拷贝技术
在 Kafka 中,高性能数据传输依赖于操作系统提供的 零拷贝(Zero-Copy) 技术,主要包括 sendfile 和 mmap 两种实现方式。它们的核心目标是减少数据在用户态和内核态之间的拷贝次数,从而提升 I/O 效率。下面详细解析它们的…...
从 0~1 保姆级 详细版 PostgreSQL 数据库安装教程
PostgreSQL数据库安装 PostgreSQL官网 【PostgreSQL官网】 | 【PostgreSQL安装官网_Windows】 安装步骤 step1: 选择与电脑相对应的PostgreSQL版本进行下载。 step2: 双击打开刚才下载好的文件。 step3: 在弹出的setup窗口中点击 …...
MySQL中常用函数的分类及示例
概述 以下是 MySQL 中常用函数的分类及示例,涵盖字符串处理、数值计算、日期操作、条件判断等常见场景: 一、字符串函数 1. CONCAT(str1, str2, ...) 拼接字符串。 SELECT CONCAT(Hello, , World); -- 输出: Hello World2. SUBSTRING(str, start,…...
【论文阅读21】-PSOSVM-CNN-GRU-Attention-滑坡预测(2024-12)
这篇论文主要提出并验证了一种新型的混合智能模型(PSOSVM-CNN-GRU-Attention),用于准确预测滑坡的点位移,并构建可靠的位移预测区间。通过对Baishuihe滑坡和Shuping滑坡的案例分析,展示了该模型的出色性能。 [1] Zai D…...
Shiro-550 动调分析与密钥正确性判断
一、Shiro 简介 Apache Shiro是一个开源安全框架,用于构建 Java 应用程序,提供身份验证、授权、加密和会话管理等功能。 二、Shiro-550(CVE-2016-4437) 1、漏洞原理 Shiro 在用户登陆时提供可选项 RememberMe,若勾选…...
Codeforces Educational Round 177 Div. 2 【B题,C待补
B 二分 题意 样例 5 3 10 3 4 2 1 512 找最右边的L下标即可 思路 二分最靠右的L端点,R端点取最右端(n*k处),找到后,答案就是L的位置(pos),(因为如果pos满足,则pos左边的所有下标都满足 代码 const in…...
【Lua语言】Lua语言快速入门
初始Lua Lua是一种轻量小巧的脚本语言,他使用标准C语言编写并以源代码形式开放。这意味着Lua虚拟机可以很方便的嵌入别的程序中,从而为应用程序提供灵活的扩展和定制功能。同时,在目前脚本引擎中,Lua的运行速度占有绝对优势。 变…...
Matlab画海洋与大气变量的时间序列并带标记面的三维折线图--来源粉丝
Matlab画带标记面的三维折线图–来源粉丝 图片 目标图: 图片 复现: 图片 细节可在代码中更改: 数据构造 clear;clc;close all; % 数据构造 X1 1:8;Y1ones(length(X1),1); X2 X1;Y22*ones(length(X1),1); X3 X1;Y33*ones(length(X1),1); …...
NestJS——多环境配置方案(dotenv、config、@nestjs/config、joi配置校验)
个人简介 👀个人主页: 前端杂货铺 🙋♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步…...
RAGFlow在Docker中运行Ollama直接运行于主机的基础URL的地址
基础Url http://host.docker.internal:11434...
python 库 下载 ,整合在一个小程序 UIUIUI
上图 import os import time import threading import requests import subprocess import importlib import tkinter as tk from tkinter import ttk, messagebox, scrolledtext from concurrent.futures import ThreadPoolExecutor, as_completed from urllib.parse import…...
【MySQL】数据库约束
个人主页:♡喜欢做梦 欢迎 👍点赞 ➕关注 ❤️收藏 💬评论 目录 ✨一、数据库的约束 🌟二、数据库约束的分类 🌍 1.非空约束(NOT NULL) 1.定义 2.格式 3.示例: 列的信息可…...
Firewalld防火墙
目录 Firewald 防火墙概述 Firewalld 简介 firewalld 与 iptables service的区别 Firewalld 网络区域 Firewalld 防火墙图形配置方法 服务选项 端口号 协议选项 源端口选项 伪装选项 端口转发 ICMP过滤器 防火墙的配置运行状态 运行时和永久有什么区别 Firewalld 防火墙 firewa…...
使用 TensorFlow 和 Keras 构建 U-Net
U-Net是图像分割领域中最为著名的架构之一。U-Net 因其形状而得名,它是一种全卷积架构,首先将图像收缩,然后将其扩展为输出结果。虽然这种收缩路径构建了一个学习特征的层次结构,但跳过连接有助于在扩展路径中将这些特征转换回相关…...
【网络篇】TCP vs UDP底层区别+网络编程概念
大家好呀 我是浪前 今天讲解的是网络篇的第三章:网络编程概念和TCP&UDP的区别 网络编程概念TCP和UDP的区别 跨主机通信:网络编程插座:网络编程的本质: 网络编程的重要概念:客户端和服务器: 客户端和服务器的交互模…...
如何保存服务器mysql数据库的数据到本地文件
打开mysql命令行如图1 图1 mysql命令行 修改文件保存路径。 在mysql安装目录下,找到my.ini文件,找到secure-file-priv变量配置的地方,修改对应的值,然后重启mysql,此时把文件放到指定路径,再执行导入导出…...
Flutter学习 滚动组件(2):ListView进阶使用
目录 前言:一、实现复杂的ListView列表:1.1 Item布局封装1.2 ListView的使用1.3 增加分割线 二、实现ListView下拉刷新:三、实现上拉加载更多:四、实现下拉刷新、上拉加载更多:五、ListView滚动方向和控制:…...
linux oracle 19c 静默安装
oracle数据库有个比较很抓瞎的事情,不同的版本搭建的大致流程是一样的,但是在实操细节上会有不同,比如操作的脚本位置和配置项等等,这些会变,所以需要时常积累不同版本的文档 这里有一点要说明,之所以使用…...
中间件--ClickHouse-11--部署示例(Linux宿主机部署,Docker容器部署)
一、Linux宿主机部署 1、环境准备 操作系统:推荐使用 CentOS 7/8 或 Ubuntu 18.04/20.04。硬件要求: 至少 2 核 CPU 和 4GB 内存。足够的磁盘空间(根据数据量评估)。CPU需支持SSE4.2指令集(可通过以下命令检查&#…...
AI调试工具有哪些?
一、深度学习框架专用调试工具 TensorBoard • 功能:实时监控训练指标(损失值、准确率)、可视化神经网络结构、分析参数分布和梯度信息 • 适用框架:TensorFlow、PyTorch(通过插件) • 特点:支持…...
Warcraft Logs [Classic] [WCL] BOSS ID query
Warcraft Logs [Classic] [WCL] BOSS ID query 所有副本BOSSID查询 https://wowpedia.fandom.com/wiki/DungeonEncounterID#Retail IDNameMapInstanceIDPatch227High Interrogator GerstahnBlackrock Depths230228Lord RoccorBlackrock Depths230229Houndmaster GrebmarBlackro…...
MySQL——事务
一、什么是事务? 事务(Transaction) 是数据库操作的最小逻辑单元,它由一组不可分割的SQL操作组成。事务的核心目标是确保多个操作要么全部成功,要么全部失败,从而维护数据的完整性。例如,银行转…...
spring Ai---向量知识库(一)
在一些垂直领域以及公司内部信息相关或者实时性相关的大模型应用,就无法直接使用chatGPT。 这个时候,向量知识库就进入了。 通过坐标向量最接近的即为匹配相关答案。 向量模型定义:将文档向量化,保证内容越相似的文本,…...
MACOS 上的 快捷指令怎么用,有哪些分享资源可以用
一、快捷指令的基本概念与历史 快捷指令(Shortcuts)是苹果生态中的自动化工具,最初以第三方应用Workflow(2014年推出)的形式出现,2017年被苹果收购后更名为Shortcuts,并深度集成到iOS、iPadOS和macOS系统中。从macOS Mojave(10.14)开始,快捷指令正式登陆Mac平台,并…...
最长子序列长度(LIS)--个数遍历的二分+贪心优化
B3637 最长上升子序列 - 洛谷 #include<bits/stdc.h> #include<string> using namespace std; #define N 100011 typedef long long ll; typedef pair<int,int> pii; int n; int g[N]; int dp[N]; int ma0; int main() { cin>>n; memset(g,0x3f,sizeo…...
RenderStage::runCameraSetUp
文章目录 RTTosg::Camera::_bufferAttachmentMapRenderStage::BufferComponent和RenderStage::_bufferAttachmentMapCamera::attach(BufferComponent buffer, GLenum internalFormat)Camera::attach(BufferComponent buffer, osg::Texture* texture.....Camera::attach(BufferC…...
突破速率瓶颈:毫米波技术如何推动 5G 网络迈向极限?
突破速率瓶颈:毫米波技术如何推动 5G 网络迈向极限? 引言 5G 网络的普及,已经让我们告别了“加载中”时代,实现了更快的数据传输、更低的延迟和更高的设备连接密度。而在 5G 技术的核心中,毫米波(mmWave&…...
前端面试真题集合(一)
一、Vue的响应式原理 Vue的响应式系统通过数据劫持和依赖追踪实现,核心流程如下: 数据劫持 • Vue 2.x:使用Object.defineProperty递归遍历数据对象,将属性转换为getter/setter,拦截属性的读取和修改操作。 • Vue 3.x:改用Proxy代理对象,支持动态属性添加和数组变化监听…...
聊聊Spring AI Alibaba的ElasticsearchDocumentReader
序 本文主要研究一下Spring AI Alibaba的ElasticsearchDocumentReader ElasticsearchDocumentReader community/document-readers/spring-ai-alibaba-starter-document-reader-elasticsearch/src/main/java/com/alibaba/cloud/ai/document/reader/es/ElasticsearchDocumentR…...