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

文章目录

  • 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 longlong long i = 0;for (i = 0; i <= x; i++) {// 如果两个数相乘正好等于 x,直接返回 iif (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

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

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode94:二叉树的中序遍历

文章目录 &#x1f60a;1.题目&#x1f609;2.解法1.递归2.迭代 &#x1f60a;1.题目 尝试一下该题 &#x1f609;2.解法 1.递归 /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* …

企业级 RAG 全链路优化关键技术

2024 云栖大会 - AI 搜索企业级 RAG 全链路优化关键技术 在2024云栖大会上&#xff0c;阿里云 AI 搜索研发负责人之一的邢少敏先生带领大家深入了解如何利用 RAG 技术优化决策支持、内容生成、智能推荐等多个核心业务场景&#xff0c;为企业数字化转型与智能化升级提供强有力的…

【Linux】了解pthread线程库,清楚并没有线程创建接口,明白Linux并不存在真正意义的线程(附带模型图详解析)

前言 大家好吖&#xff0c;欢迎来到 YY 滴Liunx系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的《Lin…

ECHO-GL:盈利电话驱动的异质图学习股票 走势预测

目录 简单概括1 背景知识相关的工作图学习在股票预测中的应用股票预测中的收益电话会议 方法异质股票图结构建造时间分配机制滑动窗机构库存空间关系模块异构边缘类型消息传递音频引导的注意聚合财报电话会议后股票动态模块预测和优化 实验消融研究 (for Q2)模拟交易 (for Q3) …

vue组件传值之$attrs

1.概述&#xff1a;$attrs用于实现当前组件的父组件&#xff0c;向当前组件的子组件通信&#xff08;祖-》孙&#xff09; 2.具体说明&#xff1a;$attrs是一个对象&#xff0c;包含所有父组件传入的标签属性。 注意&#xff1a;$attrs会自动排除props中声明的属性&#xff0…

【不要离开你的舒适圈】:猛兽才希望你落单,亲人总让你回家,4个维度全面构建舒适圈矩阵

单打独斗的英雄时代已经落幕 抱团取暖才是社会寒冬的良策 自然界中&#xff0c;每个物种都占据着自己的领地和生存空间。 生态位的差异决定了它们的生存方式&#xff0c;一旦离开领地&#xff0c;失去群体的庇护&#xff0c;就会沦为野兽的美餐。 人类社会同样存在隐形圈层…

【C++】踏上C++学习之旅(三):“我“ 与 “引用“ 的浪漫邂逅

文章目录 前言1. "引用"的概念1.1 "引用"的语法 2. "引用"的特性3. "引用"的使用场景3.1 "引用"做参数3. 2 "引用"做返回值3.2.1 "引用"做返回值时需要注意的点 4. 常引用5. "引用"在底层的实…

自动化数据处理:使用Selenium与Excel打造的数据爬取管道

随着互联网信息爆炸式增长&#xff0c;获取有效数据成为决策者的重要任务。人工爬取数据不仅耗时且效率低下&#xff0c;因此自动化数据处理成为一种高效解决方案。本文将介绍如何使用Selenium与Excel实现数据爬取与处理&#xff0c;结合代理IP技术构建一个可稳定运行的数据爬取…

RocketMQ快速开始

前置推荐阅读&#xff1a;RocketMQ简介-CSDN博客 本地部署 RocketMQ 这一节介绍如何快速部署一个单节点单副本 RocketMQ 服务&#xff0c;并完成简单的消息收发。 系统要求 64位操作系统&#xff0c;推荐 Linux/Unix/macOS64位 JDK 1.8 1.下载安装Apache RocketMQ​ RocketMQ…

aws 把vpc残留删除干净

最近忘了把vpc 删干净导致又被收了冤大头钱 在删除vpc 的收发现又eni在使用&#xff0c;但是忘了是哪个资源在占用 先用命令行把占用的资源找出来停掉 使用 AWS 命令行界面&#xff08;CLI&#xff09;来查看 VPC 的使用情况 列出子网&#xff1a; aws ec2 describe-subnets …

抖音列表页采集-前言

准备工作&#xff1a; 1.关于selenium介绍&#xff1a; python自动化入门的话&#xff0c;selenium绝对是最方便的选择&#xff0c;基本逻辑即为&#xff1a;程序模拟人的行为操作浏览器&#xff0c;这样的操作需要借用浏览器驱动&#xff0c;我选用的是chrome浏览器&#xff…

浮动练习(3)

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

港大和字节提出长视频生成模型Loong,可生成具有一致外观、大运动动态和自然场景过渡的分钟级长视频。

HKU, ByteDance&#xff5c;⭐️ 港大和字节联合提出长视频生成模型Loong&#xff0c;该模型可以生成外观一致、运动动态大、场景过渡自然的分钟级长视频。选择以统一的顺序对文本标记和视频标记进行建模&#xff0c;并使用渐进式短到长训练方案和损失重新加权来克服长视频训练…

MATLAB(Octave)混电动力能耗评估

&#x1f3af;要点 处理电动和混动汽车能耗的后向和前向算法模型(simulink)&#xff0c;以及图形函数、后处理函数等实现。构建储能元数据信息&#xff1a;电池标称特性、电池标识符等以及静止、恒定电流和恒定电压等特征阶段。使用电流脉冲或要识别的等效电路模型类型配置阻抗…

多功能纤维上线,大脑肠道 “无线畅聊” 不是梦

大家好&#xff01;今天来了解一篇多功能微电子纤维研究——《Multifunctional microelectronic fibers enable wireless modulation of gut and brain neural circuits》发表于《Nature Biotechnology》。我们都知道大脑和内脏器官的沟通对生存至关重要&#xff0c;可一直以来…

为您的 WordPress 网站打造完美广告布局 A5广告单元格插件

一个为 WordPress 网站量身定制的强大工具,它将彻底改变您展示广告的方式 灵活多变的布局设计 A5 广告单元格插件的核心优势在于其无与伦比的灵活性。无论您是想要创建整齐的网格布局,还是希望打造独特的不规则设计,这款插件都能满足您的需求。 自定义网格数量&#xff1a;从 2…

生命科学的前沿挑战与未来机遇

生命科学的前沿挑战与未来机遇 一、引言 21世纪被誉为生命科学的世纪&#xff0c;生命科学的迅猛发展为人类的健康、环境和社会经济带来了巨大的变革。从基因编辑技术的突破&#xff0c;到合成生物学的兴起&#xff0c;再到生物医药的快速进步&#xff0c;生命科学的前沿挑战…

如何使用 Browserless 抓取动态网站?

什么是动态网页&#xff1f; 动态网页是指其内容并非完全直接嵌入在静态HTML中&#xff0c;而是通过服务器端或客户端渲染生成的网页。 它可以根据用户的操作实时显示数据&#xff0c;例如在用户点击按钮或向下滚动页面时加载更多内容&#xff08;如无限滚动&#xff09;。这…

DolphinDB 2024 年度峰会回顾之分论坛:权益类数字基建与技术创新

在这个数字化时代&#xff0c;金融科技正以前所未有的速度发展&#xff0c;而权益类数字基建作为这一进程的核心支撑&#xff0c;正不断推动着金融领域的创新与变革。 DolphinDB 2024 年度峰会的分论坛 A 聚焦《权益类数字基建与技术创新》这一核心议题&#xff0c;邀请到了业…

携手并进,智驭教育!和鲸科技与智谱 AI 签署“101 数智领航计划”战略合作协议

近日&#xff0c;上海和今信息科技有限公司&#xff08;以下简称“和鲸科技”&#xff09;与北京智谱华章科技有限公司&#xff08;以下简称“智谱 AI”&#xff09;签署“101 数智领航计划”战略合作协议。双方将携手营造智能化学科教育与科研环境&#xff0c;提供多种大模型工…