二分查找总结:算法原理,适用题型,经典题单

二分查找

感谢灵神的题单

题单:分享丨【题单】二分算法(二分答案/最小化最大值/最大化最小值/第K小) - 力扣(LeetCode)

每天四道题,大概用时一个月刷完,如果没有时间的同学可以学习我总结的算法原理,适用题型,和经典的题单。

  • 二分查找
  • 算法原理
    • 1、二分查找
  • 适用题型分析
  • 经典题单
    • 2、最小完成秒数
    • 3、求满足两个数组取数规则最小的最大值
    • 4、嗑药的工人能做任务最大数
    • 5、第k小数组组合数
    • 6、相同硬币组合的第k小组合数
    • 7、第k小的乘积
    • 8、指定范围内子数组和的和
    • 9、第k大的子序列
  • 总结

算法原理

先看一张图,重点在于脑海中模拟取值区域:

在这里插入图片描述

数值越小越不能满足要求,越大越能满足要求,如果题目求最小的满足要求的值,那就是右侧区间最小的数,即为L,如果题目求最大的满足要求的值,那就是左侧区间最大的数,即为R。

每次取 [L,R] 左右区间的中间节点 (L+R)>>>1 ,如果判定大了,就移动右边界,此时中间节点相当于左移了,变小了,如果判定小了,就移动左边界,此时中间节点相当于右移,即变大了。

如何设定L和R的值,左右边界的值可以带入结果进行思考,思考结果最小可能的取值,最大可能的取值。

对于二分查找,还有一个问题,就是为什么二分的结果就是答案,有没有可能二分的结果不在数组中?

使用反证法,假设我们找的是最大的小于等于num的值,如果存在更小的值满足要求,那二分查找不会停止,如果真正的结果是更大的值,那二分查找时左端点会右移。

在实际做题时可以思考num=真实结果时左右端点移动的情况,结合上面这张图,基本没有二分边界的问题。

下面给出二分查找的java版本代码,其他语言如果有二分查找的库函数,例如Python和Golang,在清楚函数使用方法后也可以用,但是对于初学者容易搞蒙。

1、二分查找

要求在非递减数组中返回最小满足nums[i]>=target的i,如果不存在就返回n

左闭右闭区间 [left, right]

最后right+1是left,是满足nums[i]>=target的区间,而left-1是恰好不满足要求的区间

while (left <= right) { // 区间不为空// 循环不变量:// nums[left-1] < target// nums[right+1] >= targetint mid = left + (right - left) / 2;if (nums[mid] < target) {left = mid + 1; // 范围缩小到 [mid+1, right]} else {right = mid - 1; // 范围缩小到 [left, mid-1]}
}

左闭右开区间 [left, right)

while (left < right) { // 区间不为空// 循环不变量:// nums[left-1] < target// nums[right] >= targetint mid = left + (right - left) / 2;if (nums[mid] < target) {left = mid + 1; // 范围缩小到 [mid+1, right)} else {right = mid; // 范围缩小到 [left, mid)}
}

左开右开区间 (left, right)

while (left + 1 < right) { // 区间不为空// 循环不变量:// nums[left] < target// nums[right] >= targetint mid = left + (right - left) / 2;if (nums[mid] < target) {left = mid; // 范围缩小到 (mid, right)} else {right = mid; // 范围缩小到 (left, mid)}
}

适用题型分析

适合用二分查找解题的题型有

1、最小、最大

最小/大一类问题容易误判二分做法,如果没有明显的单调性,可以考虑其他做法,例如动态规化。

2、最小的最大值、最大的最小值

这一类问题比较简单,二分特征明显。

3、第K大/小

第k大/小一类问题往往在进行左右边界移动判定时比较困难,总是需要进行小于等于mid的个数是否大于等于k这一类考虑,尤其是和子数组或子序列结合的问题,更是要结合其他解题技巧,例如滑动窗口,前缀和。

在一个需要注意的是,这一类问题用最小堆可能更方便,但是有些数据范围过大,那就只能用二分,二分在处理大范围数据方便往往会有奇效。

二分查找的问题一般难在两点

1、怎么判断这道题需要用二分解决,解决误判一方面只能靠多刷题,找找感觉,另一方面如果一道题有递增递减的性质,或者在知道一个有单增性的前提条件下能更容易的解决问题,那就可以考虑用二分查找,但是有的问题需要绕一个弯才能发现递增递减,例如第9题。

2、不知道怎么写判定函数,解题技巧的问题一般发生在判定挪移左边界还是右边界的时候,这个时候总要结合其他技巧辅助解题,例如滑动窗口,数组前缀和,位运算,递归,记忆化搜索等等。这就只能靠积累了。

总结一句话:菜就多练

经典题单

2、最小完成秒数

原题速递

在这里插入图片描述
在这里插入图片描述

  • 翻译一下题目,nums是每门课需要复习的天数,change是每天可以考试的科目
  • 完成时间越多,完成概率越大,所以可以二分
  • 需要在每门最后一次考试之前完成复习,遍历,在最后一次考试时检查是否有时间复习
  • 这个题目的难点在于看出用二分,以及check函数的写法
class Solution {int[] nums;int[] changeIndices;public int earliestSecondToMarkIndices(int[] nums, int[] changeIndices) {// nums是每门课需要复习的天数,change是每天可以考试的科目// 完成时间越多,完成概率越大,所以可以二分// 需要在每门最后一次考试之前完成复习,遍历,在最后一次考试时检查是否有时间复习this.nums = nums;this.changeIndices = changeIndices;int n = changeIndices.length;int l = 1, r = n;while (l<=r){int m = (l+r)>>>1;if (check(m)) r = m-1;else l = m+1;// System.out.println(l+":"+r);}return l<=n && check(l)?l:-1;}boolean check(int time){// 是否能在time时间内完成所有考试,在最后一次考试时检查是否有时间复习int n = nums.length;// 预处理下标,得到每门课最后一次考试时间int[] last = new int[n];Arrays.fill(last,-1);for (int i=0;i<time;i++) last[changeIndices[i]-1] = i;// 是否有的科目考不了试for (int x : last) if (x==-1) return false;// 统计考试前能用的时间int cnt = 0;for (int i=0;i<time;i++){int x = changeIndices[i]-1;if (i==last[x]){// 这门课最后考试期限if (cnt<nums[x]) return false;cnt -= nums[x];}else{cnt++;}}return true;}
}

3、求满足两个数组取数规则最小的最大值

原题速递

在这里插入图片描述

  • 最大元素是x,[1,x]中整除d2的数只能在arr1中,整除d1的数只能在arr2中,不能整除d1d2的两个数组都可以放
  • x越大,越可以选出cnt1和cnt2个数,所以二分
  • 对x计算上面三个数字,如果可以满足cnt1和cnt2就修改范围
class Solution {long LCM = -1;public int minimizeSet(int d1, int d2, int cnt1, int cnt2) {// 最大元素是x,[1,x]中整除d2的数只能在arr1中,整除d1的数只能在arr2中,不能整除d1d2的两个数组都可以放// x越大,越可以选出cnt1和cnt2个数,所以二分// 对x计算上面三个数字,如果可以满足cnt1和cnt2就修改范围long l = 1, r = (cnt1+cnt2)*2-1;// d1d2最小公倍数 = d1*d2/最大公约数// 这里注意先除后乘,并且转化为long求最大公约数,以免溢出LCM = d1/gcd(d1,d2)*d2;while (l<=r){long m = (l+r)>>>1;if (check(m,d1,d2,cnt1,cnt2)) r = m-1;else l = m+1;}return (int)l;}long gcd(long x, long y){// 求最大公约数if (x==0) return y;return gcd(y%x,x);}boolean check(long m, int d1, int d2, int cnt1, int cnt2){// 是否能从[1,m]中选出cnt1,cnt2个满足要求的数long share = m/LCM;long num1 = m/d2-share;long num2 = m/d1-share;// 容斥定理long num3 = m-m/d1-m/d2+share;// 如果公用的num3不能填补两数差额,就return falsereturn num3>=Math.max(cnt1-num1,0)+Math.max(cnt2-num2,0);}
}

4、嗑药的工人能做任务最大数

原题速递

在这里插入图片描述

  • 二分任务数,难点在于如何确定在能嗑药的情况下是否能做num个任务?
  • 要求有num个任务被完成,那肯定是最强壮的num个工人,完成最小的num个任务
  • 从大到小枚举任务和工人,如果能做就continue,不能做就让最小的工人吃药丸,从而最大化药丸价值
  • 如何找最小工人?遍历到当前任务,只把吃了药丸能做的加入到队列中,这样队列中最小值就是要找的
class Solution {public int maxTaskAssign(int[] tasks, int[] workers, int pills, int strength) {// 二分任务数Arrays.sort(tasks);Arrays.sort(workers);int n = Math.min(tasks.length, workers.length);int l = 0, r = n;while (l<=r){int m = (l+r)>>>1;if (check(tasks,workers,m,pills,strength)) l = m+1;else r = m-1;}return r;}boolean check(int[] tasks, int[] workers, int num, int pills, int strength){// 要求有num个任务被完成,那肯定是最强壮的num个工人,完成最小的num个任务// 从大到小枚举任务和工人,如果能做就continue,不能做就让最小的工人吃药丸,从而最大化药丸价值// 如何找最小工人?遍历到当前任务,只把吃了药丸能做的加入到队列中,这样队列中最小值就是要找的Deque<Integer> q = new ArrayDeque();int n = workers.length, j = 1;for (int i=num-1;i>=0;i--){int t = tasks[i];// 只把吃了药丸能做的工人加入队列while (j<=num && workers[n-j]+strength>=t){q.addLast(workers[n-j]);j++;}// 没人可用if (q.isEmpty()) return false;// 最大的能做就做,否则让最小的吃药做,如果药没了就falseif (q.getFirst()>=t) q.removeFirst();else if (pills-- > 0) q.removeLast();else return false;}return true;}
}

5、第k小数组组合数

原题速递

在这里插入图片描述

  • 从每一行中选出一个数,组合成一个新的数组,求第k小的数组和
  • 暴力,数据量是 [40×40],所以可以暴力,每一行选出k个最小数,下一行相加,有k×m个组合,选出其中最小的k个,依次遍历
  • 二分,数组和越大,数组个数越多,用回溯统计数组和小于mid的个数,如果个数大于等于k就直接返回,但是二分的结果有没有可能不能由组合数得到呢?比如数组中的元素都是偶数,但是二分算出来的却是奇数,我们二分得到的是组合个数大于等于k的最小的数组和,注意这个最小,最后的结果只能是数组中的组合,不可能大于1或者小于1
  • 最小堆,本质还是暴力,在暴力中我们用数组来维护每一层的最小的k个数组和,现在可以用最小堆来计算维护数组和当前数组这两个数组的最小的前k个最小和

暴力:

class Solution {public int kthSmallest(int[][] mat, int k) {// 每行维护k个最小值,下一行m个数与这k个数相加维护前k个最小值,依次遍历int n = mat.length, m = mat[0].length;int[] nums = new int[]{0};for (int i=0;i<n;i++){int[] arr = new int[nums.length*m];int idx = 0;for (int pre : nums){for (int x : mat[i]){arr[idx++] = pre+x;}}Arrays.sort(arr);nums = Arrays.copyOfRange(arr,0,Math.min(k,arr.length));}return nums[k-1];}
}

二分:

这里需要注意一点,正常的递归是超时的,即便有剪枝优化,但还不够,还需要加上一点优化。

让sum减去第一列的和,如果当前sum小于0,就说明剩下即便每层选最小数仍然选不出新数组,进行剪枝操作。

正常的递归是,选一个数直接从sum减去即可,现在需要加上每一行最小值,再减去当前选择得数

加上这个优化就能不超时了。

class Solution {int k;int offset;public int kthSmallest(int[][] mat, int k) {// 二分数组和int n = mat.length, m = mat[0].length, sum0 = 0, sum1 = 0;for (int i=0;i<n;i++){sum0 += mat[i][0];sum1 += mat[i][m-1];}offset = n;int l = sum0, r = sum1;while (l<=r){int mid = (l+r)>>>1;this.k = k;if (dfs(n-1,mid-sum0,mat)) r = mid-1;else l = mid+1;}return Math.min(l,sum1);}boolean dfs(int i, int sum, int[][] nums){// 递归统计数组和小于等于sum的个数,如果大于等于k就return true// 在每一行中枚举元素是否可以选,如果大于数组和,就break剪枝// 正常的递归是超时的,需要加上一点优化,让sum减去第一列的和,如果当前sum小于0,就说明剩下即便每层选最小数仍然选不出新数组,进行剪枝操作// 正常来说,选一个数直接从sum减去即可,现在需要加上每一行最小值,再减去当前选择得数if (i<0) return --k==0;for (int x : nums[i]){if (x>sum+nums[i][0]) break;if (dfs(i-1,sum+nums[i][0]-x,nums)) return true;}return false;}
}

最小堆:

class Solution {public int kthSmallest(int[][] mat, int k) {// 最小堆,每一层实际上是nums和mat[i]选出前k个最小的和,可以用最小堆做int n = mat.length;int[] nums = new int[]{0};for (int i=0;i<n;i++){// 从nums和mat[i]选出前k个最小和nums = cal(nums,mat[i],k);}return nums[k-1];}int[] cal(int[] a, int[] b, int k){int n = a.length, m = b.length;int len = Math.min(k,n*m), idx = 0;int[] res = new int[len];PriorityQueue<int[]> q = new PriorityQueue<int[]>((a1,a2) -> (a1[0]-a2[0]));q.add(new int[]{a[0]+b[0],0,0});for (int i=0;i<len;i++){int[] c = q.poll();res[idx++] = c[0];int x = c[1], y = c[2];if (y==0 && x+1<n) q.offer(new int[]{a[x+1]+b[0],x+1,0});if (y+1<m) q.offer(new int[]{a[x]+b[y+1],x,y+1});}return res;}
}

6、相同硬币组合的第k小组合数

原题速递

在这里插入图片描述

  • 二分,但是怎么统计num是第几小的数呢?如果只有3个数,很好统计,a+b+c-ab-ac-bc+abc
  • 但是对于n的范围是[1,25],如何去重,还能用容斥定理吗?
  • 对于更一般的容斥定理,一个大小为size的集合,他对结果的贡献是(-1)^(size-1)*(num/lcm)
  • 累加所有非空子集的贡献,就是num第几小的数,我们可以预处理所有子集的lcm
  • 数组长度最长为15,所以我们用二进制01表示是否选这个数,枚举[0,1<<n)即可遍历所有子集
  • 优化,对于下标为i的元素,加入之前的旧子集中组成新的子集,通过或的方式计算子集的下标
class Solution {public long findKthSmallest(int[] coins, int k) {// 二分,但是怎么统计num是第几小的数呢?如果只有3个数,很好统计,a+b+c-ab-ac-bc+abc// 但是对于n的范围是[1,25],如何去重,还能用容斥定理吗?// 对于更一般的容斥定理,一个大小为size的集合,他对结果的贡献是(-1)^(size-1)*(num/lcm)// 累加所有非空子集的贡献,就是num第几小的数,我们可以预处理所有子集的lcm// 数组长度最长为15,所以我们用二进制01表示是否选这个数,枚举[0,1<<n)即可遍历所有子集// 优化,对于下标为i的元素,加入之前的旧子集中组成新的子集,通过或的方式计算子集的下标int n = coins.length;// 如果全选,就是111...111,开辟大小为1<<n的数组long[] lcms = new long[1 << n];// 初始化,全不选的lcm是1lcms[0] = 1;for (int i=0;i<n;i++){// 第i个数与之前的集合进行两两组合可以得到新的集合,此时旧集合是mask,新元素是第i个数// 则新的集合是 (1<<i)|maskint bit = 1<<i;for (int mask=0;mask<bit;mask++){lcms[mask|bit] = lcm(lcms[mask], coins[i]);}}// 二分long minv = Long.MAX_VALUE;for (int x : coins) minv = Math.min(minv,x);long l = minv, r = minv*k;while (l<=r){long mid = (l+r)>>>1;if (check(mid,lcms,n,k)) r = mid-1;else l = mid+1;}return Math.min(l,minv*k);}long lcm(long a, long b){return a*b/gcd(a,b);}long gcd(long a, long b){if (a==0) return b;return gcd(b%a,a);}boolean check(long num,long[] lcms,int n, int k){// 统计小于等于num的个数,如果大于等于k就true,否则falselong cnt = 0;for (int i=1;i<(1<<n);i++){if (Integer.bitCount(i)%2==1){// 奇数个1,选了奇数个数,加号cnt += num/lcms[i];}else{cnt -= num/lcms[i];}}return cnt>=k;}
}

7、第k小的乘积

原题速递

在这里插入图片描述

  • 数组的范围太大,最小堆预计超时,25e8,那就用二分
  • 如果只有正数,那很简单,遍历数组一,找数组二中小于除数的个数
  • 但是存在负数,所以要分类讨论,首先计算所有乘积在负数,0,正数的个数
  • 例如[-4,-2,0,3],[2,4],6,负数乘积四个,0有两个,正数乘积两个,6=4+2,正好是0
  • 如果k小于等于负数,或者大于等于正数,就进行二分

8、指定范围内子数组和的和

原题速递

在这里插入图片描述

  • 暴力做法,求所有n(n+1)/2个子数组的和,排序,求和[l,r]即可
  • 如果能求出最小的r个子数组的和,减去最小的l-1个子数组的和,就得到区间和
  • 二分+前缀和求得第k小的子数组的和num
  • 通过子数组和的前缀和求得小于num的个数为cnt,并根据前缀和数组求总和sum
  • 则等于num的个数为k-cnt,总和=sum+num*(k-cnt)
  • 这个算法的关键在于前缀和pre的前缀和prePre,如果前缀和的和prePre符合要求的统计区间在[i,j],我们直接前缀和的和相减的结果prePre[j]-prePre[i]是会多加一个pre[i]的,需要对每一项减去pre[i],即减去(j-i)*pre[i]
class Solution {static final int mod = (int)1e9+7;public int rangeSum(int[] nums, int n, int left, int right) {// 暴力做法,求所有n(n+1)/2个子数组的和,排序,求和[l,r]即可// 如果能求出最小的r个子数组的和,减去最小的l-1个子数组的和,就得到区间和// 二分+前缀和求得第k小的子数组的和num// 通过子数组和的前缀和求得小于num的个数为cnt,并根据前缀和数组求总和sum// 则等于num的个数为k-cnt,总和=sum+num*(k-cnt)// 这个算法的关键在于前缀和的前缀和,int[] pre = new int[n+1];for (int i=0;i<n;i++) pre[i+1] = pre[i]+nums[i];int[] prePre = new int[n+1];for (int i=0;i<n;i++) prePre[i+1] = prePre[i]+pre[i+1];return cal(pre,prePre,n,right) - cal(pre,prePre,n,left-1);}int cal(int[] pre, int[] prePre, int n, int k){// 计算前k个最小子数组和的和// 首先,计算第k小的子数组和int num = getK(pre,n,k);// 其次,统计小于num的子数组和的个数// 遍历i,找prePre[j]<prePre[i]+num的j的个数,累加到cnt上,并维护子数组和的和int sum = 0, cnt = 0;for (int i=0, j=1;i<n;i++){while (j<=n && pre[j]-pre[i]<num){j++;}j--;cnt += j-i;// 计算子数组和小于num的和,第一部分前缀相减表示[i,j]结尾的前缀和,每一项都多加了pre[i],需要减去sum = (sum+prePre[j]-prePre[i]-pre[i]*(j-i))%mod;}// 最后,加上等于num的部分,就得到小于等于num的前k个子数组和的和。sum = (sum+num*(k-cnt))%mod;return sum;}int getK(int[] pre, int n, int k){// 计算第k小的子数组和if (k==0) return 0;int l = 0, r = pre[n];while (l<=r){int m = (l+r)>>>1;if (check(m,pre,n,k)) r = m-1;else l = m+1;}return Math.min(l,pre[n]);}boolean check(int num, int[] pre, int n, int k){// 如果小于等于num的个数大于等于k,就true,否则false// 遍历i,pre[i]+num>=pre[j],统计j的下标int cnt = 0;for (int i=0, j=1;i<n;i++){while (j<=n && pre[j]-pre[i]<=num){j++;}j--;cnt += j-i;if (cnt>=k) return true;}return false;}
}

9、第k大的子序列

原题速递

在这里插入图片描述

  • 最大的子序列的和=所有正数相加,之后减去正数或者加上负数都会导致和减小,即减去绝对值
  • 每次减去最小的绝对值就能得到第k+1大的子序列和,减去的数越多,子序列和越小,有单调性
  • 计算正数和sum,在[0,绝对值之和]范围内对子序列和进行二分,dfs找第k小的子序列和,用sum减去即可
class Solution {public long kSum(int[] nums, int k) {// 最大的子序列的和=所有正数相加,之后减去正数或者加上负数都会导致和减小,即减去绝对值// 每次减去最小的绝对值就能得到第k+1大的子序列和,减去的数越多,子序列和越小,有单调性// 计算正数和sum,在[0,绝对值之和]范围内对子序列和进行二分,dfs找第k小的子序列和,用sum减去即可long sum = 0, maxAbs = 0;int n = nums.length;for (int i=0;i<n;i++){if (nums[i]>=0) sum += nums[i];else nums[i] = -nums[i];maxAbs += nums[i];}Arrays.sort(nums);long l = 0, r = maxAbs;while (l<=r){long m = (l+r)>>>1;// 选或不选递归统计子序列,如果选了,就是一个合法子序列,cnt++// cnt反向递归,如果为0,就判定为true,首先排除空子序列这种情况cnt = k-1;dfs(0,nums,m);// 如果小于等于m的子序列的个数大于等于k,就移动右边界if (cnt==0) r = m-1;else l = m+1;} return sum-Math.min(l,maxAbs);}int cnt;void dfs(int i, int[] nums, long sum){if (i==nums.length || sum<nums[i] || cnt==0) return;// 选cnt--;dfs(i+1,nums,sum-nums[i]);// 不选dfs(i+1,nums,sum); }
}

总结

在刷完题单后依然感觉面对较难的题目无从下手,我的猜测是两方面原因

一方面,算法题是需要积累的,这是一个过程,可能是长时间的苦练,也可能是一时的开窍

另一方面,解题是多方面的,而非单个二分查找可以以偏概全,需要积累技巧和解题思路。

总之,还得努力。

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

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

相关文章

递归解析 LXML 树并避免重复进入某个节点

1、问题背景 我们在使用 LXML 库解析 MathML 表达式时&#xff0c;可能会遇到这样一个问题&#xff1a;在递归解析过程中&#xff0c;我们可能会重复进入同一个节点&#xff0c;导致解析结果不正确。例如&#xff0c;我们希望将以下 MathML 表达式解析为 Python 表达式&#x…

类别朴素贝叶斯CategoricalNB和西瓜数据集

CategoricalNB 1 CategoricalNB原理以及用法2 数据集2.1 西瓜数据集2.2 LabelEncoder2.3 OrdinalEncoder 3 代码实现 1 CategoricalNB原理以及用法 &#xff08;1&#xff09;具体原理 具体原理可看&#xff1a;贝叶斯分类器原理 sklearn之CategoricalNB对条件概率的原理如下&…

Ant-design-vue开源项目介绍、应用场景、组件有哪些

文章目录 一、Ant-design-vue项目介绍二、Ant-design-vue项目特点三、Ant-design-vue应用场景四、Ant-design-vue有哪些组件五、Ant-design-vue案例代码1. 后台管理系统登录页面的例子2. Table组件使用案例 开源项目地址 一、Ant-design-vue项目介绍 Ant-design-vue 是一个基于…

java:spring使用【@ImportResource】导入一个xml里面定义的bean

# 项目代码资源&#xff1a; 可能还在审核中&#xff0c;请等待。。。 https://download.csdn.net/download/chenhz2284/89434148 # 项目代码 【pom.xml】 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-start…

【C语言】递归复杂度与链表OJ之双指针

【C语言】递归复杂度与链表OJ之双指针 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;数据结构 文章目录 【C语言】递归复杂度与链表OJ之双指针前言一.递归复杂度1.1递归时间复杂度1.2递归空间复杂度 二.链表OJ之双指针2.1倒数第K个节点2.2链…

微信小程序查分易如何使用?

期末马上到了&#xff0c;老师们又开始为发放成绩而头疼了&#xff0c;堆积如山的试卷&#xff0c;密密麻麻的分数&#xff0c;还有那些不断响起的家长电话&#xff0c;真是让人心烦。别担心&#xff0c;今天就让我来介绍一个让老师“偷懒”神器——查分易微信小程序 第一步&am…

汇编中标签的引用$符号

一个c/c开发人员&#xff0c;居然不会汇编&#xff0c;真是惭愧。趁着闲暇时间学习一下汇编&#xff0c;曲不离口&#xff0c;码不离手。看一个简单的例子&#xff1a; .section .datavalue:.quad 200.section .text .global main main:nopMOVL value, %eaxret 就这一条指令&…

大数据------JavaWeb------前端知识点汇总

额外知识点 W3C标准&#xff1a;W3C是万维网联盟&#xff0c;这个组成是用来定义标准的。他们规定了一个网页是由三部分组成 结构&#xff1a;对应的是 HTML 语言表现&#xff1a;对应的是 CSS 语言行为&#xff1a;对应的是 JavaScript 语言 HTML定义页面的整体结构&#xff1…

端口占用多:UE4/UE5像素流送云推流时如何优化端口使用?

许多用户反映&#xff0c;在使用UE4或UE5进行像素流送云推流时&#xff0c;端口的占用数量较多。这促使我们思考&#xff0c;是否有方案能够减少这种资源占用&#xff1f; 目前&#xff0c;像素流送技术对于端口的要求是每个独立用户占用一个端口。 然而&#xff0c;但在实际…

渗透测试信息收集

信息收集简介 信息收集&#xff08;Information Gathering&#xff09;&#xff0c;信息收集是指通过各种方式获取所需要的信息。信息收集是信息得以利用的第一步&#xff0c;也是关键的一步。信息收集工作的好坏&#xff0c;直接关系到整个信息管理工作的质量。信息可以分为原…

编译原理:语法分析之LR分析

自底向上分析方法&#xff08;LR分析算法&#xff09;bottom-up parsing 引言. 运算符 LR(0)LR(0)的项&#xff08;构建有穷自动机的状态&#xff09;LR(0)的项目闭包&#xff08;构建有穷自动机的状态&#xff09;GOTO函数有效项目LR(0)有穷自动机的构建 SLRLR(1)LALR 引言 L…

解析FTP服务器:从基础知识到vsftpd实战操作

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

另辟蹊径的终端防病毒

在数字时代的浪潮中&#xff0c;网络安全问题愈发凸显&#xff0c;防病毒成为了保护信息安全的重要一环。而白名单作为一种有效的安全策略&#xff0c;在防病毒方面发挥着不可或缺的作用。 首先&#xff0c;我们需要明确白名单的概念。白名单是一种管理和安全实践&#xff0c;用…

【leetcode--单词规律】

题目要求&#xff1a; 跟上一个字符串的思路一致&#xff0c;只是要进行单词的拆分&#xff0c;用.split()函数即可。 class Solution:def wordPattern(self, pattern: str, s: str) -> bool:word s.split()if(len(pattern) ! len(word)):return Falsereturn len(set(patt…

吴恩达2022机器学习专项课程C2W3:2.25 理解方差和偏差(诊断方差偏差正则化偏差方案搭建性能学习曲线)

目录 引言名词替代影响模型偏差和方差的因素1.多项式阶数2.正则化参数 判断是否有高偏差或高方差1.方法一&#xff1a;建立性能基准水平2.方法二&#xff1a;建立学习曲线 总结 引言 机器学习系统开发的典型流程是从一个想法开始&#xff0c;然后训练模型。初次训练的结果通常…

【docker】Linux安装最新版Docker完整教程

这里写目录标题 一、安装前准备工作1.1、安装依赖包1.2、设置阿里云镜像源 二、安装Docker2.1、docker-ce安装2.2、启动docker2.3、启动docker并设置开机自启 三、 优化docker配置3.1、访问阿里云官方镜像加速器地址3.2、设置阿里云加速地址 一、安装前准备工作 1.1、安装依赖…

资源分享—2021版乡级制图规范符号库

汇总整理超图平台软件相关的各类资源&#xff08;包括但不限于符号库、地图模板、地理处理模型等&#xff09;&#xff0c;助力项目的高效制图、提高数据生产效率等业务。 本次分享新版国土空间规划【2021版乡级制图规范符号库】&#xff0c;提供SuperMap格式符号库下载。 符…

信号与系统实验MATLAB-实验1-信号的MATLAB表示及信号运算

实验1-信号的MATLAB表示及信号运算 一、实验目的 1、掌握MATLAB的使用&#xff1b; 2、掌握MATLAB生成信号波形&#xff1b; 3、掌握MATLAB分析常用连续信号&#xff1b; 4、掌握信号运算的MATLAB实现。 二、实验内容 编写程序实现下列常用函数&#xff0c;并显示波形。…

python返回每个数 青少年编程电子学会python编程等级考试三级真题解析2021年9月

python返回每个数 2021年9月 python编程等级考试级编程题 一、题目要求 1、编程实现 给定一个整数 num&#xff0c;从1到 num 按照下面的规则返回每个数! 如果这个数被 3 整除&#xff0c;返回 Apple。 如果这个数被 5 整除&#xff0c;返回Pie’。 如果这个数能同时被 3 和…

竟然与 package-lock.json 更新有关!部分用户 H5 页面白屏问题!

一.问题 1 场景 现象 接到部分用户反馈进入xxx H5 页面空白&#xff1b; 研发测日志里问题用户的线上页面URL地址可以正常访问&#xff0c;没有复现问题&#xff01;&#xff01;&#xff01; 定位问题 监控平台和客户端日志报错&#xff1a; SyntaxError: Unexpected toke…