【优选算法篇】在分割中追寻秩序:二分查找的智慧轨迹

文章目录

  • C++ 二分查找详解:基础题解与思维分析
    • 前言
    • 第一章:热身练习
      • 1.1 二分查找基本实现
        • 解题思路
        • 图解分析
        • C++代码实现
        • 易错点提示
        • 代码解读
      • 1.2 在排序数组中查找元素的第一个和最后一个位置
        • 解题思路
        • 1.2.1 查找左边界
          • 算法步骤:
          • 图解分析
          • C++代码实现
        • 1.2.2 查找右边界
          • 算法步骤:
          • 图解分析
          • C++代码实现
        • 1.2.3 组合查找结果
          • C++完整代码
      • 1.3 搜索插入位置
        • 解题思路
        • 1.3.1 二分查找算法分析
          • 算法步骤:
          • 图解分析
          • C++代码实现
          • 易错点提示
          • 代码解读
      • 1.4 x 的平方根
          • 解题思路
        • 1.4.1 暴力查找
          • 算法步骤:
          • C++代码实现
          • 图解分析
        • 1.4.2 二分查找法
          • 算法步骤:
          • 图解分析
          • C++代码实现
          • 易错点提示
          • 代码解读
    • 写在最后
      • 二分查找算法总结
      • 重要的三点:
      • 模板记忆技巧
      • 两段式的特殊处理:

C++ 二分查找详解:基础题解与思维分析

💬 欢迎讨论:如有疑问或见解,欢迎在评论区留言互动。

👍 点赞、收藏与分享:如觉得这篇文章对您有帮助,请点赞、收藏并分享!
🚀 分享给更多人:欢迎分享给更多对 C++ 感兴趣的朋友,一起学习二分查找的基础与进阶!


前言

二分查找法是经典的搜索算法之一,能够在有序数组中快速查找目标元素。它的时间复杂度为 O(log n),相比于线性搜索有着更高的效率。本篇博客将详细分析二分查找的原理,并结合题目讲解,帮助大家全面掌握这一重要的算法技巧。


第一章:热身练习

1.1 二分查找基本实现

题目链接:704. 二分查找

题目描述

给定一个升序排列的整数数组 nums,和一个目标值 target。如果 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

提示

  • 你可以假设数组中的所有元素是互不相同的。
  • 数组 nums 的长度范围为 [1, 10000]
  • 数组 nums 的每个元素都在 [-9999, 9999] 之间。

解题思路

二分查找的核心思想是利用数组的有序性,通过每次将查找范围缩小一半来快速锁定目标位置。我们在数组的中间位置进行比较,根据比较结果判断应该继续在左侧还是右侧进行查找。

具体思路如下:

  1. 初始化左右指针

    • left 指向数组的起始位置。
    • right 指向数组的末尾位置。
  2. 计算中间位置

    • 通过公式 mid = left + (right - left) / 2 来计算中间位置 mid这个公式可以避免直接相加 left + right 可能导致的整数溢出。
  3. 比较中间元素与目标值

    • 如果 nums[mid] == target,则直接返回 mid
    • 如果 nums[mid] > target,说明目标值在左半部分,此时应将 right 更新为 mid - 1
    • 如果 nums[mid] < target,说明目标值在右半部分,此时应将 left 更新为 mid + 1
  4. 结束条件

    • left > right 时,说明查找范围为空,目标值不存在,返回 -1

图解分析

假设数组 nums = [-1, 0, 3, 5, 9, 12],目标值 target = 9。我们从数组的中间位置开始查找:

  1. 初始状态

    • left = 0right = 5
    • 中间位置 mid = (0 + 5) / 2 = 2nums[mid] = 3
    • 因为 3 < 9,所以更新 left = mid + 1 = 3
  2. 步骤 1

    • left = 3right = 5
    • 中间位置 mid = (3 + 5) / 2 = 4nums[mid] = 9
    • 找到目标值 9,返回下标 4

步骤图解

Iterationleft Pointerright Pointermid PointerArray State
1052[-1, 0, 3, 5, 9, 12]
2354[5, 9, 12]

C++代码实现
class Solution {
public:
    int search(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) {
                return mid; // 找到目标,返回下标
            } else if (nums[mid] > target) {
                right = mid - 1; // 缩小查找范围至左半部分
            } else {
                left = mid + 1;  // 缩小查找范围至右半部分
            }
        }
        
        return -1; // 未找到目标,返回 -1
    }
};

易错点提示
  1. 防止溢出:计算中间位置时,建议使用 mid = left + (right - left) / 2,而不是 mid = (left + right) / 2,这样可以避免 left + right 直接相加时可能的整数溢出问题。
  2. 循环条件while (left <= right),当 leftright 指向相同元素时,仍然需要继续判断,因此需要取等号。
  3. 边界条件处理:如果目标值不存在于数组中,应返回 -1,避免返回无效的数组下标。

代码解读
  • 时间复杂度:每次查找都会将查找范围缩小一半,因此时间复杂度为 O(log n)
  • 空间复杂度:该算法仅使用了少量额外的变量,空间复杂度为 O(1)

1.2 在排序数组中查找元素的第一个和最后一个位置

题目链接:34. 在排序数组中查找元素的第一个和最后一个位置

题目描述

给定一个按非递减顺序排列的整数数组 nums,和一个目标值 target,请找出给定目标值在数组中的开始位置结束位置

如果数组中不存在目标值 target,返回 [-1, -1]

示例 1

  • 输入:nums = [5,7,7,8,8,10], target = 8
  • 输出:[3, 4]
  • 解释:目标值 8 在数组中的起始位置为下标 3,结束位置为下标 4

示例 2

  • 输入:nums = [5,7,7,8,8,10], target = 6
  • 输出:[-1, -1]
  • 解释:目标值 6 不存在于数组中,因此返回 [-1, -1]

示例 3

  • 输入:nums = [], target = 0
  • 输出:[-1, -1]
  • 解释:空数组中没有任何目标值,因此返回 [-1, -1]

提示

  • 0 <= nums.length <= 105
  • -109 <= nums[i] <= 109
  • nums 是一个非递减数组。
  • -109 <= target <= 109

解题思路

我们需要在时间复杂度 O(log n) 内找到目标值的起始位置结束位置,这意味着必须使用二分查找来解决问题。

基本思路:通过两次二分查找,分别找到目标值的左边界和右边界。

  1. 左边界:找到数组中第一个等于目标值的位置。
  2. 右边界:找到数组中最后一个等于目标值的位置。

接下来分别介绍如何查找这两个边界。


1.2.1 查找左边界

我们首先使用二分查找来确定目标值的起始位置,即左边界。

算法步骤:
  1. 初始化左右指针

    • left 指向数组的起始位置,right 指向数组的末尾位置。
  2. 进行二分查找

    • 计算中间位置 mid = left + (right - left) / 2
    • 如果 nums[mid] 小于目标值 target,则说明目标值在右边,因此更新 left = mid + 1
    • 如果 nums[mid] 大于或等于目标值,说明目标值在左边(包括 mid 位置),因此更新 right = mid
  3. 结束条件:当 left == right 时,查找结束。此时需要检查 nums[left] 是否等于目标值,如果相等,返回该位置;否则返回 -1


图解分析

假设数组为 nums = [5,7,7,8,8,10],目标值为 target = 8。我们从数组的中间位置开始查找:

  1. 初始状态

    • left = 0, right = 5
    • 计算中间位置 mid = (0 + 5) / 2 = 2,此时 nums[mid] = 7
    • 因为 7 < 8,所以更新 left = mid + 1 = 3
  2. 步骤 1

    • left = 3, right = 5
    • 计算中间位置 mid = (3 + 5) / 2 = 4,此时 nums[mid] = 8
    • 因为 nums[mid] >= 8,所以更新 right = mid = 4
  3. 步骤 2

    • left = 3, right = 4
    • 计算中间位置 mid = (3 + 4) / 2 = 3,此时 nums[mid] = 8
    • 因为 nums[mid] >= 8,所以更新 right = mid = 3
  4. 结束状态

    • 此时 left == right == 3,我们检查 nums[left] == 8,因此找到了目标值的起始位置 3

C++代码实现
class Solution {
public:
    int searchLeft(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.size() == 0 || nums[left] != target) return -1;  // 边界条件检查
        return left;
    }
};

1.2.2 查找右边界

接下来,我们使用二分查找找到目标值的结束位置,即右边界。

算法步骤:
  1. 初始化左右指针

    • left 指向数组的起始位置,right 指向数组的末尾位置。
  2. 进行二分查找

    • 计算中间位置 mid = left + (right - left + 1) / 2(向上取整)。
    • 如果 nums[mid] 小于等于目标值 target,则更新 left = mid
    • 如果 nums[mid] 大于目标值,说明目标值在左边,因此更新 right = mid - 1
  3. 结束条件:当 left == right 时,查找结束,此时 left 指向目标值的结束位置。


图解分析

假设数组为 nums = [5,7,7,8,8,10],目标值为 target = 8。我们从中间位置开始查找结束位置:

  1. 初始状态

    • left = 0, right = 5
    • 计算 mid = (0 + 5 + 1) / 2 = 3,此时 nums[mid] = 8
    • 因为 nums[mid] <= 8,所以更新 left = mid = 3
  2. 步骤 1

    • left = 3, right = 5
    • 计算 mid = (3 + 5 + 1) / 2 = 4,此时 nums[mid] = 8
    • 因为 nums[mid] <= 8,所以更新 left = mid = 4
  3. 步骤 2

    • left = 4, right = 5
    • 计算 mid = (4 + 5 + 1) / 2 = 5,此时 nums[mid] = 10
    • 因为 nums[mid] > 8,所以更新 right = mid - 1 = 4
  4. 结束状态

    • 此时 left == right == 4,因此找到了目标值的结束位置 4

C++代码实现
class Solution {
public:
    int searchRight(vector<int>& nums, int target) {
        int left = 0, 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 left;  // 此时 left 指向最后一个目标值的位置
    }
};

1.2.3 组合查找结果

最后,我们将左边界和右边界的查找结果组合起来。如果左边

界的查找结果为 -1,则说明目标值不存在,返回 [-1, -1]。否则,返回 [left, right]

C++完整代码
class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int left = searchLeft(nums, target);
        if (left == -1) return {-1, -1};  // 目标值不存在
        
        int right = searchRight(nums, target);
        return {left, right};  // 返回目标值的起始和结束位置
    }
};

1.3 搜索插入位置

题目链接:35. 搜索插入位置

题目描述

给定一个排序数组 nums 和一个目标值 target,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

你必须设计并实现时间复杂度为 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

提示:

  • 1 <= nums.length <= 104
  • 104 <= nums[i] <= 104
  • nums 为 无重复元素 的 升序 排列数组
  • 104 <= target <= 104

解题思路

该题的要求是以 O(log n) 的时间复杂度找到目标值或者其应该插入的位置,因此我们必须使用二分查找。通过二分查找,我们可以在每次查找中将搜索范围缩小一半,进而快速锁定目标值的位置,或者它应插入的准确位置。


1.3.1 二分查找算法分析

在这道题中,我们通过二分查找来确定目标值的位置。如果目标值存在,直接返回其索引;如果不存在,我们可以通过查找过程中的边界情况确定它的插入位置。

算法步骤:
  1. 初始化左右指针

    • left 指向数组的起始位置,right 指向数组的末尾位置。
  2. 进行二分查找

    • 计算中间位置 mid = left + (right - left) / 2
    • 如果 nums[mid] 小于目标值 target,则目标值可能出现在右边部分,因此更新 left = mid + 1
    • 如果 nums[mid] 大于或等于目标值,说明目标值可能在左边部分,因此更新 right = mid
  3. 结束条件:当 left == right 时,查找结束。此时的 leftright 所在的位置就是目标值应插入的位置。


图解分析

假设数组为 nums = [1,3,5,6],目标值 target = 5。我们从数组的中间位置开始查找目标值的位置或插入位置:

  1. 初始状态

    • left = 0right = 3
    • 计算中间位置 mid = (0 + 3) / 2 = 1,此时 nums[mid] = 3
    • 因为 3 < 5,更新 left = mid + 1 = 2
  2. 步骤 1

    • left = 2right = 3
    • 计算中间位置 mid = (2 + 3) / 2 = 2,此时 nums[mid] = 5
    • 因为 nums[mid] == 5,找到目标值,返回下标 2
  3. 插入位置场景

    • 如果 target = 2,则当 left = 0right = 1 时,nums[mid] = 1,更新 left = 1,最后返回 1 作为插入位置。

步骤图解

Iterationleft Pointerright Pointermid PointerArray State
1031[1, 3, 5, 6]
2232[5, 6]

C++代码实现
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;  // 缩小查找范围至左半部分
            }
        }
        
        // 最终结果在 left 或 right 位置
        if (nums[left] < target) return left + 1;
        return left;
    }
};

易错点提示
  1. 二分查找的边界条件:要确保循环结束条件是 left == right,这意味着在查找结束后,leftright 位置就是插入点。
  2. 处理插入位置的返回值:当 nums[left] 小于 target 时,表示目标值应插入到 left + 1 的位置,否则插入到 left 位置。

代码解读
  • 时间复杂度:每次查找都会将查找范围缩小一半,因此时间复杂度为 O(log n)
  • 空间复杂度:该算法仅使用了少量的额外变量,空间复杂度为 O(1)

1.4 x 的平方根

题目链接:69. x 的平方根

题目描述

给定一个非负整数 x,计算并返回 x算术平方根。由于返回类型是整数,结果只保留整数部分,小数部分将被舍去

注意不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5

示例 1

  • 输入:x = 4
  • 输出:2

示例 2

  • 输入:x = 8
  • 输出:2
  • 解释:8 的算术平方根是 2.82842...,由于返回类型是整数,小数部分将被舍去。

提示:

  • 0 <= x <= 2^31 - 1

解题思路

我们可以通过暴力查找和二分查找两种方法来解决该问题。

暴力查找方法简单直接,逐个枚举可能的平方根,直到找到符合条件的数为止。
二分查找方法则更加高效,利用有序性质通过缩小区间的方式快速锁定平方根。

接下来我们分别详细介绍这两种方法。


1.4.1 暴力查找

暴力查找法的核心思想是从 0 开始枚举所有可能的平方根 i,依次判断 i * i 是否等于或超过目标值 x。一旦找到符合条件的 i,就可以直接返回结果。

算法步骤:
  1. 遍历所有可能的数:从 i = 0 开始,逐一检查 i * i 是否等于 x 或者超过 x
  2. 判断条件
    • 如果 i * i == x,说明找到了平方根,直接返回 i
    • 如果 i * i > x,说明 i 已经超出目标值的平方,返回前一个数 i - 1 作为平方根。
C++代码实现
class Solution {
public:
    int mySqrt(int x) {
        // 由于两个较大的数相乘可能会超过 int 最大范围,因此用 long long
        long long i = 0;
        for (i = 0; i <= x; i++) {
            // 如果两个数相乘正好等于 x,直接返回 i
            if (i * i == x) return i;
            // 如果第一次出现两个数相乘大于 x,说明结果是前一个数
            if (i * i > x) return i - 1;
        }
        // 处理边界情况
        return -1;
    }
};

图解分析

假设 x = 8,我们逐个枚举所有可能的平方根:

  1. 初始状态
    • i = 0i * i = 0,继续下一次循环。
  2. 步骤 1
    • i = 1i * i = 1,继续下一次循环。
  3. 步骤 2
    • i = 2i * i = 4,继续下一次循环。
  4. 步骤 3
    • i = 3i * i = 9,此时 9 > 8,返回前一个数 2 作为平方根。

暴力法的优缺点

  • 优点:实现简单,直观。
  • 缺点:对于较大的输入,时间复杂度为 O(x^1/2),效率较低。

1.4.2 二分查找法

二分查找法是一种更高效的方式,通过利用平方根的有序性,在查找过程中不断缩小区间,快速找到平方根。

算法步骤:
  1. 初始化左右指针
    • left 指向 1right 指向 x
  2. 进行二分查找
    • 计算中间位置 mid = left + (right - left + 1) / 2
    • 如果 mid * mid <= x,说明平方根可能在右半部分,更新 left = mid
    • 如果 mid * mid > x,说明平方根在左半部分,更新 right = mid - 1
  3. 结束条件:当 left == right 时,查找结束,此时 left 就是平方根。

图解分析

假设 x = 8,我们通过二分查找来找到平方根:

  1. 初始状态
    • left = 1right = 8
    • 计算 mid = (1 + 8 + 1) / 2 = 5,此时 5 * 5 = 25 > 8,更新 right = 4
  2. 步骤 1
    • left = 1right = 4
    • 计算 mid = (1 + 4 + 1) / 2 = 3,此时 3 * 3 = 9 > 8,更新 right = 2
  3. 步骤 2
    • left = 1right = 2
    • 计算 mid = (1 + 2 + 1) / 2 = 2,此时 2 * 2 = 4 <= 8,更新 left = 2

结束状态:当 left == right == 2,我们找到了平方根 2


C++代码实现
class Solution {
public:
    int mySqrt(int x) {
        if (x < 1) return 0; // 处理边界情况
        int left = 1, right = x;
        
        while (left < right) {
            long long mid = left + (right - left + 1) / 2; // 防止溢出
            if (mid * mid <= x) {
                left = mid;  // 继续向右半部分查找
            } else {
                right = mid - 1;  // 继续向左半部分查找
            }
        }
        
        return left;  // 返回平方根
    }
};

易错点提示
  1. 防止溢出:在计算中间位置 mid 时,使用 long long 类型,以避免 mid * mid 超出 int 的范围导致溢出。
  2. 边界条件:需要正确处理 x = 0x = 1 的情况。

代码解读
  • 时间复杂度:每次查找都会将查找范围缩小一半,因此时间复杂度为 O(log n)
  • 空间复杂度:仅使用了常数级的额外空间,空间复杂度为 O(1)

写在最后

二分查找算法总结

二分查找并不是通过死记模板就能轻松解决所有问题的。其核心在于分析题意,并据此确定搜索区间。理解问题背后的逻辑,明确要搜索的区间,才能灵活编写二分查找的代码。模板只是工具,关键在于理解和应用。

重要的三点:

  • 分析题意,确定搜索区间:根据不同的题目,合理分析查找的区间,避免死记硬套模板。
  • 理解区间变化:明确什么时候该舍弃左边区间,什么时候舍弃右边区间,并根据题目特点动态调整指针。
  • 不要纠结模板形式:不必执着于左闭右开、左闭右闭等模板,最重要的是理解算法背后的区间划分逻辑。

模板记忆技巧

  1. 三段式与两段式的选择
    • 在面对不同题目时,不要强行套用模板。通过分析问题中的搜索区间变化,合理选择三段式(左右都参与)或两段式(左右边界一边不参与)。

两段式的特殊处理:

在二分查找中,如何处理中间值 mid 的计算至关重要,特别是在更新左右指针的情况下,需要正确地选择向上取整或向下取整,否则可能会出现死循环。

  • left = mid:为了避免死循环,应当向上取整。因为此时 left 不变,如果不向上取整,mid 将会一直是 left,无法突破当前的循环状态,导致死循环。

    • 计算公式为:mid = left + (right - left + 1) / 2
  • right = mid:应当向下取整。这样可以保证每次 right 都会减少,逐步缩小搜索区间。

    • 计算公式为:mid = left + (right - left) / 2

以上就是关于【优选算法篇】在分割中追寻秩序:二分查找的智慧轨迹啦的内容啦,各位大佬有什么问题欢迎在评论区指正,您的支持是我创作的最大动力!❤️

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

国产大模型基础能力大比拼 - 计数:通义千文 vs 文心一言 vs 智谱 vs 讯飞-正经应用场景的 LLM 逻辑测试

在大语言模型&#xff08;LLM&#xff09;不断涌现的时代&#xff0c;如何评估这些国产大模型的逻辑推理能力&#xff0c;尤其是在处理基础计数问题上的表现&#xff0c;成为了一个备受关注的话题。随着越来越多的国产大模型进入市场&#xff0c;比较它们在不同任务中的表现尤为…

群晖通过 Docker 安装 Gitea

1. 准备工作 1.1 安装 docker 套件 2.2 安装MySQL&#xff08;可选&#xff09; 群晖通过 Docker 安装 MySQL-CSDN博客 如果安装了MySQL&#xff0c;可以创建gitea用户和gitea_db数据库&#xff0c;并且赋予权限 #创建数据库 CREATE DATABASE gitea_db; #确认数据库已创建…

【Jenkins】2024 最新版本的 Jenkins 权限修改为 root 用户启动,解决 permission-denied 报错问题

最新版本的 Jenkins 修改 /etc/sysconfig/jenkins 中的 JENKINS_USERroot不会再生效&#xff0c;需要按照以下配置进行操作&#xff1a; vim /usr/lib/systemd/system/jenkins.service然后重启就可以了 systemctl daemon-reload # 重新加载 systemd 的配置文件 systemctl res…

JavaEE 多线程第三节 (lambda方法实现多线程/Thread属性和方法/前台线程后台线程)

欢迎阅读前序课程JavaEE 多线程第二节 (多线程的简单实现Thread/Runable)-CSDN博客 1. lambda方法实现多线程 public class Test {public static void main(String[] args) throws InterruptedException {Thread t new Thread(()->{while (true){System.out.println("…

探索云边缘与边缘云:技术革新与应用前景

#1024程序员节&#xff5c;征文# 在当今数字化快速发展的时代&#xff0c;云计算已经成为了企业和个人处理和存储数据的重要手段。然而&#xff0c;随着物联网&#xff08;IoT&#xff09;设备的爆炸式增长以及对低延迟、高带宽和实时处理的需求不断增加&#xff0c;云边缘和边…

简单介绍市面上的四款录屏软件!!!!

数字化时代&#xff0c;无论是工作还是生活中&#xff0c;录屏已经成为一个不可或缺的工具。然而&#xff0c;选择一款适合自己需求的录屏软件却并不容易。今日来为大家推荐四款超好用的录屏软件&#xff0c;分析这些软件的优缺点&#xff0c;让你在各种场景下都能轻松捕捉精彩…

vue3 解决背景图与窗口留有间隙的问题

需要实现一个登录界面&#xff0c;login.vue的代码如下&#xff1a; <script> import { ref } from vue;export default {setup() {return {};}, }; </script><template><div id"login-container" class"login-container"><di…

Tcp协议讲解与守护进程

TCP协议&#xff1a;面向链接&#xff0c;面向字节流&#xff0c;可靠通信 创建tcp_server 1.创建套接字 域&#xff1a;依旧选择AF_INET 连接方式&#xff1a; 选择SOCK_STREAM 可靠的 2.bind 3.监听装置 client要通信&#xff0c;要先建立连接&#xff0…

Allegro怎么批量将弧形线改成45度角的线?

Allegro如何将弧形线改成45度角的线? 在用Allegro进行PCB设计时,有时候需要将弧形线改为45度角的线。 具体操作方法如下: 1、选择菜单栏Route 选择Unsupported Prototypes(不支持的原型)→AICC 2、在Options选项卡选择45度 3、在Find选项卡选择Nets,选择网络可以批量转换…

浮动练习(3)

##每台电脑分辨率不同&#xff0c;数值高度宽度需要自己调&#xff0c;仅供参考 <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title></title> <style> div{ …

JMeter详细介绍和相关概念

JMeter是一款开源的、强大的、用于进行性能测试和功能测试的Java应用程序。 本篇承接上一篇 JMeter快速入门示例 &#xff0c; 对该篇中出现的相关概念进行详细介绍。 JMeter测试计划 测试计划名称和注释&#xff1a;整个测试脚本保存的名称&#xff0c;以及对该测试计划的注…

《使用Gin框架构建分布式应用》阅读笔记:p108-p126

《用Gin框架构建分布式应用》学习第8天&#xff0c;p108-p126总结&#xff0c;总计18页。 一、技术总结 1.Redis eviction policy (1)什么是 eviction policy? The eviction policy determines what happens when a database reaches its memory limit. (2)配置示例 在r…

Dockerfile样例

一、基础jar镜像制作 ## Dockerfile FROM registry.openanolis.cn/openanolis/anolisos:8.9 RUN mkdir /work ADD jdk17.tar.gz fonts.tar.gz /work/ RUN yum install fontconfig ttmkfdir -y && yum clean all && \chmod -R 755 /work/fonts ADD fonts.conf …

docker配置mysql8报错 ERROR 2002 (HY000)

通过docker启动的mysql&#xff0c;发现navicat无法连接&#xff0c;后来进入容器内部也是无法连接&#xff0c;产生以下错误 root9f3b90339a14:/var/run/mysqld# mysql -u root -p Enter password: ERROR 2002 (HY000): Cant connect to local MySQL server through socket …

二叉树中的最长交错路径

题目链接 二叉树中的最长交错路径 题目描述 注意点 每棵树最多有 50000 个节点每个节点的值在 [1, 100] 之间起点无需是根节点 解答思路 要找到最长交错路径&#xff0c;首先想到的是深度优先遍历因为起点无需是根节点&#xff0c;所以对于任意一个节点&#xff0c;其可以…

4个在线音频剪辑工具,让你的声音更加动听。

最近我开始接触音乐剪辑&#xff0c;想把一些歌曲进行剪辑创作&#xff1b;于是在网上好多了很多的音频剪辑软件进行试用&#xff0c;一番下来&#xff0c;发现了4款使用起来体验感比较好的专业剪辑工具&#xff0c;在这里跟大家分享分享。这些工具都可以被应用于歌曲创作&…

Linux系统基础-进程间通信(3)_模拟实现匿名管道

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 Linux系统基础-进程间通信(3)_模拟实现匿名和命名管道 收录于专栏[Linux学习] 本专栏旨在分享学习Linux的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&a…

【优先算法】--双指针1

“一念既出&#xff0c;万山无阻。”加油陌生人&#xff01; 目录 1.双指针--移动零 2.双指针-复写零 ok&#xff0c;首先在学习之前&#xff0c;为了方便大家后面的学习&#xff0c;我们这里需要补充一个知识点&#xff0c;我这里所谓的指针&#xff0c;不是之前学习的带有…

dolphinscheduler创建工作流及工作流中DataX的使用(简单操作)

一、在项目管理中创建项目&#xff1a;点击创建项目 用哪个用户登录的&#xff0c;所属用户就是哪个&#xff0c;直接输入项目名即可 二、点击项目&#xff0c;在项目中创建工作流&#xff0c;用DataX同步数据 按照图片的步骤依次填写完成&#xff0c;注意 图片中的第九步是写…

2024年双十一腾讯阿里云香港服务器优惠活动汇总

2024年双11狂欢节终于来了&#xff0c;按照往年的惯例&#xff0c;各大云服务器厂商通常会在10月20号左右开始上线新的活动&#xff0c;今年双11期间国内各大云服务器厂商都有哪些活动呢&#xff1f;有哪些活动包括香港云服务器呢&#xff1f;是否有海外服务器的优惠折扣呢&…