二分思想与相关例题(上)

news2024/11/25 19:24:17

在上一篇浅谈二分思想中,我们谈到了提过二分的本质,其实就是不断折半,折到最后折无可折的那个结果就是最符合要求的结果。

现在我们从答案出发,对答案的整体可能范围不断二分,最后找到最合适的答案。我们称这种方法为二分答案法。

二分答案法:
  1. 估计 最终答案可能的范围 是什么
  2. 分析 问题的答案给定条件 之间的单调性 ,这种分析往往只需要简单分析。
  3. 建立一个 f f f函数,当答案固定的情况下,判断给定的条件是否达标。
  4. 最终答案可能的范围上不断二分搜索,每次用 f f f函数判断, 直到二分结束,找到最合适的答案

核心点:分析单调性、建立 f f f函数

P r o b l e m 1 Problem1 Problem1 爱吃香蕉的珂珂 LeetCode 875

珂珂喜欢吃香蕉。这里有 n 堆香蕉,第 i 堆中有 piles[i] 根香蕉。警卫已经离开了,将在 h 小时后回来。

珂珂可以决定她吃香蕉的速度 k (单位:根/小时)。每个小时,她将会选择一堆香蕉,从中吃掉 k 根。如果这堆香蕉少于 k 根,她将吃掉这堆的所有香蕉,然后这一小时内不会再吃更多的香蕉。

珂珂喜欢慢慢吃,但仍然想在警卫回来前吃掉所有的香蕉。

返回她可以在 h 小时内吃掉所有香蕉的最小速度 kk 为整数)。

示例 1:

输入:piles = [3,6,7,11], h = 8
输出:4

示例 2:

输入:piles = [30,11,23,4,20], h = 5
输出:30

示例 3:

输入:piles = [30,11,23,4,20], h = 6
输出:23

提示:

  • 1 <= piles.length <= 104
  • piles.length <= h <= 109
  • 1 <= piles[i] <= 109
问题分析:

我们先贪心地想,既然吃香蕉的速度为 k k k,那为了在有限时间内吃掉更多堆香蕉,我们应该要优先吃掉 香蕉数量不大于 k k k 的堆,对于 香蕉数量大于 k k k 的堆,我们也要优先吃掉 香蕉数量较少 的堆。所以我们要先对 p i l e s [ i ] piles[i] piles[i]进行升序排序,然后从左往右 一个堆一个堆地 去吃。

现在吃香蕉堆的顺序确定下来了,但是如果吃的速度太慢( k k k太小),就算选择了最优顺序也不能在 h h h小时内吃掉所有香蕉。所以我们要增大吃香蕉的速度 k k k,很容易发现, k k k越小,越可能吃不完, k k k越大,在 h h h小时内越可能吃完所有香蕉。

按照刚刚的分析,我们知道能否在 h h h小时内吃完所有香蕉相对于**吃香蕉的速度( k k k)**是单调的,草图如下:

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/3b96977d6bfa4d4cb07e32116439d1c9.jpeg#pic_center)

所以我们可以可能利用二分来寻找最小的 k k k

好了,现在我们就来详细讨论一下是怎么个二分法,二分法的代码应该怎样去写

​ 因为吃香蕉的速度肯定不小于 0 0 0,所以初始左边界 l e f t = 0 left = 0 left=0,那右边界呢?按道理我们选一个非常大的数作为右边界就可以,但是这样会使得我们二分的次数增多,浪费时间,所以我们应该找到符合题目情况的合理右边界。

​ 我们在最开始的贪心分析中,不是对 p i l e s [ i ] piles[i] piles[i]排了序嘛,如果 p i l e s [ i ] piles[i] piles[i]的最大值 p i l e s [ N − 1 ] piles[N-1] piles[N1]都比 k k k小,那就说明珂珂每吃一次就可以吃掉一堆,毫无疑问地符合条件,所以我们就把右边界 r i g h t right right取值为 p i l e s [ N − 1 ] piles[N-1] piles[N1]

​ 现在轮到 m i d mid mid了, m i d = ( l e f t + r i g h t ) / 2 mid = (left + right) / 2 mid=(left+right)/2,当 m i d mid mid满足条件:吃香蕉速度为 m i d mid mid时,珂珂能在 h h h小时内吃完所有香蕉,我们就把右边界 r i g h t right right赋值为 m i d mid mid。当 m i d mid mid不满足条件时,我们就把左边界 l e f t left left赋值为 m i d + 1 mid + 1 mid+1

​ 当区间被二分缩小到一位数或者左边界 l e f t left left大于右边界 r i g h t right right时,我们取出 r i g h t right right作为最终值。

以上就是二分部分的讨论,那现在就剩下 k k k是否满足条件 的问题上来了。

其实也很简单,从左往右一个堆一个堆地吃,统计每个堆需要吃的次数再求和就可以了。

解决代码:
bool check_Pro1(int lamda, vector<int>& new_piles, int h) {
        if (lamda == 0)
            return false;
        long sum = 0;
        for (int i = 0; i < new_piles.size(); i++) {
            sum += (new_piles[i] / lamda) + (new_piles[i] % lamda == 0 ? 0 : 1);
        }
        if (sum > h)
            return false;
        return true;
}

int solution_Pro1(vector<int> piles, int h) {
    sort(piles.begin(), piles.end());
    int left = 0;
    int right = piles[piles.size() - 1];

    while (left < right) {
        int mid = (left + right) / 2;
        check_Pro1(mid, piles, h) ? right = mid : left = mid + 1;
    }
    return right;
}
P r o b l e m 2 Problem2 Problem2 分割数组的最大值 LeetCode 410

给定一个非负整数数组 nums 和一个整数 k ,你需要将这个数组分成 k 个非空的连续子数组。

设计一个算法使得这 k 个子数组各自和的最大值最小。

示例 1:

输入:nums = [7,2,5,10,8], k = 2
输出:18
解释:
一共有四种方法将 nums 分割为 2 个子数组。 
其中最好的方式是将其分为 [7,2,5] 和 [10,8] 。
因为此时这两个子数组各自的和的最大值为18,在所有情况中最小。

示例 2:

输入:nums = [1,2,3,4,5], k = 2
输出:9

示例 3:

输入:nums = [1,4,4], k = 3
输出:4

提示:

  • 1 <= nums.length <= 1000
  • 0 <= nums[i] <= 106
  • 1 <= k <= min(50, nums.length)

问题分析:

这显然是一个最小化最大值问题,基本上也要用到二分思想,这个二分基本上是对 需要最小化的变量 进行二分。

我们记某种划分得到的 k k k个子数组各自和的最大值为 s c o r e score score,用数学公式来表示,其实就是:
m a x ( 每部分的和 s u m ) max(每部分的和sum) max(每部分的和sum)
题目要求返回的是 s c o r e score score的最小值,所以我们要使 m a x ( 每部分的和 s u m ) max(每部分的和sum) max(每部分的和sum)尽可能的小。现在我们来分析一下 s c o r e score score的可能取值范围吧,也就是分析范围区间的左边界 l e f t left left与右边界 r i g h t right right。【一般在分析边界的时候,都往极端情况去分析,极端情况更可能出现最值嘛】

​ 数组nums是非负整数数组,所以每部分的和 s u m sum sum至少由一个数构成,而 s c o r e score score又是各自和的最大值,所以 s c o r e score score的值不可能小于 n u m s nums nums中的最大值,我们记为 m a x max max,那么区间的左边界 l e f t left left我们可以定为 m a x max max,那区间的右边界呢?区间的右边界自然是每部分和的最大可能取值,我们知道,非负整数数组的某个子数组累加和一定不会大于整体累加和,我们把数组nums的整体累加和记为 A A A,则区间的右边界应该定为 A A A

分析到这里,我们知道了 s c o r e score score的可能取值范围,现在就需要寻找 s c o r e score score与哪种问题条件之间具有单调性了,根据单调性我们才可以进行二分寻找最合适的答案。

我们从 s c o r e score score入手,一般而言, s c o r e score score越大,数组和为 s c o r e score score的那个区间中的数字个数会越多一点,其他区间中的数字个数也可以略微增加一些,只要保证区间数组和不大于 s c o r e score score。每个区间的数字个数多了,但是总数组的数字也就只有N个,这就说明区间的个数少了嘛。所以我们可以得出:

​ 【结论2-1】 子数组各自和的最大值 s c o r e score score越大,其对应的至少区间个数越小。

相应地,我们提出如下问题:

​ 【问题2-1】给定一个非负整数数组nums,要想将其分裂成一个个连续的子数组,并且保证这些连续子数组的各自和的最大值为 s c o r e score score,请问至少需要划分成几个子数组?

如果 s c o r e score score的值 A 1 A_1 A1时对应的子数组个数为 a a a s c o r e score score的值为 A 2 A_2 A2时对应的子数组个数为 b b b,根据【结论1】,可以得出 b < = a b <= a b<=a

回到二分查找条件上来,如果 s c o r e = m i d score = mid score=mid时,其对应的【问题2-1】的解小于k,说明我们能给出这么一种划分,将整个数组nums份成 k k k个子数组并且子数组各自和的最大值为 s c o r e score score。那说明这个 m i d mid mid取值是满足题目条件的,所以我们缩小区间 r i g h t = m i d right = mid right=mid。如果 m i d mid mid不满足条件(【问题2-1】的解大于 k k k),那我们就要选择 s c o r e score score取值较大的那一片区间, l e f t = m i d + 1 left = mid +1 left=mid+1

至此,二分的初始范围二分查找条件都已经分析完毕。

现在只剩下【问题2-1】的解决方案,这个解决方案其实也比较简单,需要用到贪心思想。

​ 我们贪心地想,一个子区间的区间累加和越大,这个子区间的长度一般来说会越大,对整个数组nums来说,如果每个子区间的区间累加和尽可能地逼近 s c o r e score score(但小于 s c o r e score score),那整个数组被划分之后的子区间数量会尽可能地少。

直接看下面这段解决代码你就明白了:

解决代码:
int check_Pro2(vector<int>& nums, int score) {
    int ans = 1;
    int subSum = 0; //记录子区间的累加和

    for (int i = 0;i < nums.size();i++) {
        subSum += nums[i];
        if (subSum > score) {
            ans++;
            subSum = nums[i];
        }
    }
    return ans;
}

int solution_Pro2(vector<int>& nums, int k) {
    int sum = 0;
    int max = 0;
    for (int num : nums) {
        sum += num;
        max = num > max ? num : max;
    }

    //主体二分框架
    int left = max;
    int right = sum;

    while (left < right) {
        int mid = (left + right) / 2;
        if (check_Pro2(nums, mid) > k) {
            left = mid + 1;
        }
        else {
            right = mid;
        }
    }
    return right;
}
P r o b l e m 3 Problem3 Problem3 机器人跳跃问题 nowcoder ZJ24

机器人正在玩一个古老的基于DOS的游戏。游戏中有 N + 1 N+1 N+1座建筑——从 0 0 0 N N N编号,从左到右排列。

编号为 0 0 0的建筑高度为0个单位,编号为 i i i的建筑的高度为 H i H_i Hi个单位。

起初, 机器人在编号为0的建筑处。每一步,它跳到下一个(右边)建筑。假设机器人在第k个建筑,且它现在的能量值是 E E E, 下一步它将跳到第 k + 1 k+1 k+1个建筑。它将会得到或者失去正比于与 H k + 1 H_{k+1} Hk+1 E E E之差的能量。如果$ H_{k+1}> E$ 那么机器人就失去 H k + 1 − E H_{k+1} - E Hk+1E 的能量值,否则它将得到$ E - H_{k+1}$ 的能量值。

游戏目标是到达第N个建筑,在这个过程中,能量值不能为负数个单位。现在的问题是机器人以多少能量值开始游戏,才可以保证成功完成游戏?

输入描述:

第一行输入,表示一共有 N 组数据

第二个是 N 个空格分隔的整数, H 1 , H 2 , H 3 , . . . , H n H_1, H_2, H_3, ..., H_n H1,H2,H3,...,Hn 代表建筑物的高度

输出描述:

输出一个单独的数表示完成游戏所需的最少单位的初始能量

示例:

输入:5
	 3 4 3 2 4
输出:4
问题分析:

问题最后要返回的是,机器人能够成功完成游戏需要的最少能量值,而成功完成游戏代表着什么呢?代表着从初始位置开始,机器人向右一步一步跳直到跳到终点第 N + 1 N+1 N+1个建筑的过程中,在中途从未出现过能量值为负的情况。

我们记机器人的初始能量值为 e n e r g y energy energy,一般而言, e n e r g y energy energy越大,每跳一步失去的能量值或者得到的能量值越大,在游戏过程中能量值耗尽的可能性就越小,即完成游戏就越容易。所以我们可以分析出 能否成功完成游戏与初始能量值 之间是具有单调性的,函数图如下:

在这里插入图片描述

现在我们来讨论这道题的二分框架。我们很容易想到,能量 e n e r g y energy energy不能为负,所以左边界。当 e n e r g y energy energy比这些建筑的最大高度还大时,机器人在跳跃过程中会畅通无阻,所以我们将右边界 r i g h t right right设置为 m a x max max m a x max max为这些建筑的最大高度】。

二分筛选也很简单,如果初始值为 m i d mid mid时不能成功完成游戏,那我们就需要选择较大的区间: l e f t = m i d + 1 left = mid + 1 left=mid+1,如果可以完成游戏,我们就选择较小的区间来逼近 e n e r g y energy energy的最小值: r i g h t = m i d right = mid right=mid

好了,现在又只剩下一个问题:

​ 给定初始能量值 e n e r g y energy energy,机器人能否成功完成游戏,能则返回 t r u e true true,否则返回 f a l s e false false

这个问题我暂时想不出来有什么简单的解法,只能带着 e n e r g y energy energy一步步跳,中途如果 e n e r g y energy energy为负,则直接返回 f a l s e false false,若到达终点时 e n e r g y energy energy仍非负,则返回 t r u e true true

解决代码:
bool check_Pro3(vector<int> Heights, int N, int energy, int max) {
    for (int i = 0; i < N; i++) {
        if (energy >= Heights[i]) {
            energy += (energy - Heights[i]);
        } else   energy -= (Heights[i] - energy);

        if (energy >= max)    return true;
        if (energy < 0)   return false;
    }
    return true;
}

int main() {
    int N;
    cin >> N;
    vector<int> Heights(N);
    int max = 0;
    for (int i = 0; i < N; i++) {
        int num ;
        cin >> num;
        Heights[i] = num;
        max = max > Heights[i] ? max : Heights[i];
    }

    int left = 0;
    int right = max;
    int answer = right;

    while (left <= right) { // 使用 <= 保证区间收敛
        int mid = (left + right) / 2;
        if (check_Pro3(Heights, N, mid, max)) {
            answer = mid; // 保存当前可行的解
            right = mid - 1; // 尝试更小的能量
        } else {
            left = mid + 1; // 增加能量
        }
    }
    cout << answer;

    return 0;
}

【注意】 我们以上代码解释两点:

  1. check函数中设置if (energy >= max) return true;是因为如果不加限制地让 e n e r g y energy energy一直这么加下去, e n e r g y energy energy很有可能会超过int甚至long数据类型的表示范围,所以我们要适当地进行剪枝。在某一时刻 e n e r g y energy energy比最大值 m a x max max还要大,那么之后的建筑机器人一定可以到达,所以我们提前返回true
  2. 第二点是针对于二分的,如果 m i d mid mid满足条件,我们就用answer去存储这个当前可行解,之后再利用right = mid - 1left = mid +1来收敛二分区间。

我们再来看今天这篇文章的最后一题

P r o b l e m 4 Problem4 Problem4 找出第K小的数对距离

数对 (a,b) 由整数 ab 组成,其数对距离定义为 ab 的绝对差值。

给你一个整数数组 nums 和一个整数 k ,数对由 nums[i]nums[j] 组成且满足 0 <= i < j < nums.length 。返回 所有数对距离中k 小的数对距离。

示例 1:

输入:nums = [1,3,1], k = 1
输出:0
解释:数对和对应的距离如下:
(1,3) -> 2
(1,1) -> 0
(3,1) -> 2
距离第 1 小的数对是 (1,1) ,距离为 0 。

示例 2:

输入:nums = [1,1,1], k = 2
输出:0

示例 3:

输入:nums = [1,6,1], k = 3
输出:5

提示:

  • n == nums.length
  • 2 <= n <= 104
  • 0 <= nums[i] <= 106
  • 1 <= k <= n * (n - 1) / 2

问题分析:

乍一看,这道题和前三道题有些许不同,前三道题都是最大化…或者最小化…问题,这道题只需要选择第 k k k小的数对距离。所以我们需要思考一下怎么对这个第 k k k小的数对距离问题进行转换,转换成可以进行二分答案的问题。

我们记数对距离为 p a i r D i s t a n c e pairDistance pairDistance,由于数对有很多种,所以 p a i r D i s t a n c e pairDistance pairDistance也有很多取值,出现重复取值的情况也比较常见。对于二分答案来说,不管取值的情况是连续的还是零散的,我们只想要知道 p a i r D i s t a n c e pairDistance pairDistance取值的左边界和右边界。

​ 左边界显然易见,因为数对距离是两个数 a , b a,b a,b之间的差值的绝对值,所以左边界 l e f t = 0 left = 0 left=0,右边界也很简单,数组的最大值减去最小值就是差值的最大值,也就是所有数对距离中的最大值嘛,如果我们对整个数组从小到大进行排序的话,右边界 r i g h t = n u m s [ N − 1 ] − n u m s [ 0 ] right = nums[N-1]- nums[0] right=nums[N1]nums[0]

现在我们需要思考一下 p a i r D i s t a n c e pairDistance pairDistance跟什么东西放一起讨论具有函数单调性呢,这个东西最好还要和题目所给条件有关。

​ 回想一下,我们还从未讨论过第 k k k小这个条件,如果这个数对距离【我们记为 p a i r D i s t a n c e k pairDistance_k pairDistancek】是第k小的,那么在它之间一定有第1小【 p a i r D i s t a n c e 1 pairDistance1 pairDistance1】、… 、 第 k − 1 k-1 k1小【 p a i r D i s t a n c e k − 1 pairDistance_{k-1} pairDistancek1】的数对距离。根据这个我们可以知道, p a i r D i s t a n c e pairDistance pairDistance越大,比它小的数对距离就越多。

我们回到二分框架的 m i d mid mid上,如果数对距离为 m i d mid mid时,数对距离小于或等于 m i d mid mid的数对个数 大于或等于 k k k,说明答案在整个区间的左半部分,这时我们要 a n s w e r = m i d , r i g h t = m i d − 1 answer = mid,right = mid-1 answer=mid,right=mid1来收敛区间和保留当前可行解【疑点1】,如果数对距离大于 m i d mid mid的数对个数大于 k k k,那说明答案在整个区间的右半部分,我们要 l e f t = m i d + 1 left = mid +1 left=mid+1来选取右半部分进行区间收敛并选取可行解【疑点2】。

现在我们只剩下一个问题需要解决:

​ 【问题4-1】给定一个整数 d i s t a n c e distance distance,数对距离小于或等于 d i s t a n c e distance distance的数对有多少个?

在最开始分析的时候,我们已经对数组进行了排序,所以数对距离就是数对中 下标大的数 减去 下标小的数 。回到【问题4-1】,这个问题其实有暴力解法,我把所有的数对都遍历一遍,拎出 数对距离小于或等于 d i s t a n c e distance distance 的数对进行计数就好了,但是这种操作的时间复杂度是 O ( n ∗ ( n − 1 ) / 2 ) O(n*(n-1)/2) O(n(n1)/2),肯定会超时。

看过我之前文章的同学可能会想到,我之前写过一篇 【滑动窗口遍历数组】的文章,利用滑动窗口可以在 带着目的 的情况下大大减少遍历数组的时间。

我们直接给出解决【问题4-1】的代码:

bool check_Pro4(vector<int> nums, int distance, int k) {
    int left = 0;
    int ans = 0;
    while (left < nums.size() - 1) {
        int right = left + 1;
        while (nums[right] - nums[left] <= distance) {
            //数对距离比distance小,窗口可以继续往右移
            ans++;
            right++;
        }
        left++;
    }
    return ans <= k;
}
解决代码:

现在只剩个二分主框架:

int solution_Pro4(vector<int> nums, int k) {
    sort(nums.begin(), nums.end());
    int left = 0, right = nums[nums.size() - 1];
    int answer;
    while (left <= right) {
        int mid = (left + right) / 2;
        if (check_Pro4(nums, mid, k)) {
            answer = mid;
            right = mid - 1;
        }
        else {
            left = mid + 1;
        }
    }
    return answer;
}

在第四题末尾补充一下对两个疑点的解释:

  1. 数对距离为 m i d mid mid时,数对距离小于或等于 m i d mid mid的数对个数 大于或等于 k k k,这对应着两种情况。第一种情况: m i d mid mid的值和真正第 k k k小的值不相等,那我们利用 r i g h t = m i d − 1 right = mid -1 right=mid1来收敛区间没问题,即使加上 a n s w e r = m i d answer = mid answer=mid也不会影响最终的 a n s w e r answer answer,因为真正第 k k k小的值在收敛后的区间里,它会对 a n s w e r answer answer进行更新。第二种情况: m i d mid mid的值和真正第 k k k小的值相等,这个时候我们仍然在利用 r i g h t = m i d − 1 right = mid-1 right=mid1收敛区间,如果不加上$answer = mid ,那真正第 ,那真正第 ,那真正第k 小的值就被我们错过了,这显然要出问题,所以最后我们选定 小的值就被我们错过了,这显然要出问题,所以最后我们选定 小的值就被我们错过了,这显然要出问题,所以最后我们选定answer = mid, right = mid - 1$。
  2. 如果 数对距离小于或等于 m i d mid mid的数对个数小于 k k k,那说明 m i d mid mid是第 m m m小的数,这个 m m m一定小于 k k k,所以我们只需要选取右半部分区间来进行收敛,只需要 l e f t = m i d + 1 left = mid +1 left=mid+1即可。

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

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

相关文章

Visual Studio安装教程

这次我给大家讲一下Visual Studio安装 一、官网下载 官网下载地址&#xff1a;https://visualstudio.microsoft.com/zh-hans/downloads/ 下载下来的是一个.exe文件 双击打开&#xff0c;出现下面的界面 二、安装visual studio &#xff08;一&#xff09;更改安装路径 首先&am…

Oracle数据恢复—Oracle数据库误删除表数据如何恢复数据?

删除Oracle数据库数据一般有以下2种方式&#xff1a;delete、drop或truncate。下面针对这2种删除oracle数据库数据的方式探讨一下oracle数据库数据恢复方法&#xff08;不考虑全库备份和利用归档日志&#xff09;。 1、delete误删除的数据恢复方法。 利用oracle提供的闪回方法…

小程序——生命周期

文章目录 运行机制更新机制生命周期介绍应用级别生命周期页面级别生命周期组件生命周期生命周期两个细节补充说明总结 运行机制 用一张图简要概述一下小程序的运行机制 冷启动与热启动&#xff1a; 小程序启动可以分为两种情况&#xff0c;一种是冷启动&#xff0c;一种是热…

202409011在飞凌的OK3588-C的核心板跑Rockchip原厂的Android12时挂载触摸屏ft5x06之后使用i2c-tools检测

1|console:/ # i2cdetect --version console:/ # i2cdetect -l console:/ # i2cdetect -F 7 console:/ # i2cdetect -a -y 7 1|console:/ # i2cdump --version console:/ # i2cdump -f -y 7 0x38 202409011在飞凌的OK3588-C的核心板跑Rockchip原厂的Android12时挂载触摸屏ft5x0…

基于SpringBoot+Vue+MySQL的瑜伽馆管理系统

系统展示 用户前台界面 管理员后台界面 系统背景 本系统采用SpringBoot作为后端框架&#xff0c;Vue.js构建前端用户界面&#xff0c;MySQL作为数据库存储系统&#xff0c;实现了瑜伽馆的全面数字化管理。系统涵盖会员管理、课程预约、教练排班、收入统计等功能模块&#xff0c…

苍穹外卖Day01

文章目录 目录 文章目录 前端环境搭建 后端环境搭建 后端-数据库环境搭建 前后端联调 前端环境搭建 打开文件夹&#xff08;确保nginx在英文目录下&#xff09;双击ngnix.exe启动nginx服务&#xff0c;访问端口号80在地址栏输入localhost打开界面 后端环境搭建 熟悉项目…

Node.js运行环境搭建

【图书介绍】《Node.jsMongoDBVue.js全栈开发实战》-CSDN博客 《Node.jsMongoDBVue.js全栈开发实战&#xff08;Web前端技术丛书&#xff09;》(邹琼俊)【摘要 书评 试读】- 京东图书 (jd.com) 本节介绍如何搭建Node.js运行环境。 1.2.1 Node.js运行环境安装 进入Node.js官…

淘宝 npmmirror 镜像站的使用

1、访问网址 https://npmmirror.com/ 2、由于国内直接使用 npm 的官方镜像是非常慢的&#xff0c;推荐使用淘宝 NPM 镜像。 淘宝 NPM 镜像是一个完整 npmjs.org 镜像&#xff0c;可以用于代替官方版本。 3、操作方法也非常的简单&#xff0c;只需要在安装完npm后&#xff0…

数据结构:堆的算法

目录 一堆的向上调整算法二堆的向下调整算法三堆的应用:堆排序四TOPK问题 一堆的向上调整算法 我们在堆中插入一个数据一般实在堆的最后插入然后可以一步一步与上层结点&#xff08;父结点进行比较&#xff09;&#xff0c;继而进行交换&#xff0c;完成二叉树的结构&#xff0…

Spring Cloud之三 网关 Gateway

1:Intellij 新建项目 spring-cloud-gateway 2:pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLoca…

Vulnhub靶场 DC-2

靶机地址:https://www.vulnhub.com/entry/dc-2,311/ 导入到VMware里面去, 设置NAT模式 namp扫描一下c段获取ip地址, 然后再扫描ip地址获取详细的信息 得到ip 192.168.75.134 无法访问 按照下面这个方法可以访问了 在kali上的处理 flag1 网站上就存在 提示了一个cewl工具,…

【Unity踩坑】使用Input System后UI EventSystem的冲突

在项目中使用Input System&#xff0c;在UI中添加了元素后&#xff0c;再次运行出现下面的错误&#xff1a; InvalidOperationException: You are trying to read Input using the UnityEngine.Input class, but you have switched active Input handling to Input System pac…

基于SpringBoot+Vue+MySQL的考编论坛网站

系统展示 用户前台界面 管理员后台界面 系统背景 在当前信息化高速发展的时代&#xff0c;考编已成为众多求职者的重要选择。然而&#xff0c;备考过程中信息获取、经验交流及资源分享的需求日益凸显。基于SpringBoot、Vue.js与MySQL构建的考编论坛网站应运而生&#xff0c;旨在…

微软面向所有用户推出 Xbox Game Pass Standard

2024 年 8 月下旬&#xff0c;微软启动了 Xbox Game Pass Standard 的公开测试&#xff0c;这是其不断发展的 Game Pass 套餐中的一个新层级。几周后的今天&#xff0c;Xbox Game Pass 标准版已向支持地区的所有 Xbox 用户开放。 Xbox Game Pass 标准版每月收费 14.99 美元。以…

【可测试性实践】C++ 单元测试代码覆盖率统计入门

引言 最近在调研C工程怎么做单元测试和代码覆盖率统计&#xff0c;由于我们工程有使用Boost库&#xff0c;尝试使用Boost.Test来实现单元测试并通过Gcov和Lcov来生成代码覆盖率报告。本文记录完整的搭建测试Demo&#xff0c;希望能带来一定参考。 常用C单测框架对比 特性Goo…

实时系统资源监测:AutoPowerOptionsOK确保电脑性能与节能兼备

科技赋予生活翅膀&#xff0c;让我们在快节奏中翱翔&#xff0c;协调工作与梦想&#xff0c;让每一个梦想都有机会照进现实&#xff0c;绽放光彩——科技的进步不仅推动了社会的发展&#xff0c;也极大地改善了人们的日常生活。在众多科技成果中&#xff0c;电脑作为信息处理的…

Day8 | Java框架 | Maven

Day8 | Java框架 | Maven 分模块开发与设计分模块开发意义分模块开发步骤&#xff08;模块拆分&#xff09; 依赖管理概念依赖传递可选依赖与排除依赖 继承与聚合聚合继承 属性属性配置与使用资源文件引用属性版本管理 多环境配置与应用多环境开发跳过测试&#xff08;了解&…

场外期权是什么?个人可以参与场外期权交易吗?

今天期权懂带你了解场外期权是什么?个人可以参与场外期权交易吗?通过了解场外期权的特点、优点和缺点&#xff0c;投资者可以更好地决定是否使用这种工具进行风险管理或投资操作。 场外期权是什么? 场外期权是指通过私下协商而非在公开交易所交易的期权合约。以下是关于场…

Python基础语法(1)下

输入输出 和用户交互 程序需要和用户进行交互。 用户把信息传递给程序的过程&#xff0c;称为 "输入"&#xff0c;也就是用户给计算机下命令就叫做输入。 程序把结果展示给用户的过程&#xff0c;称为 "输出"&#xff0c;也就是计算机在向用户汇报工作…

【Hot100】LeetCode—139. 单词拆分

目录 1- 思路题目识别完全背包-动规五部曲 2- 实现⭐单词拆分——题解思路 3- ACM 实现 原题链接&#xff1a;139. 单词拆分 1- 思路 题目识别 识别1 &#xff1a;字符串 和一个 字符串数组 判断识别2&#xff1a;判断字符串能不能由字符串数组拼接形成&#xff0c;返回 true…