JavaScript算法描述【排序与搜索】六大经典排序|搜索旋转排序数组|在排序数组中查找元素的第一个和最后一个位置、数组中的第K个|

news2024/12/23 6:00:49

🐧主页详情:Choice~的个人主页

文章目录

    • 搜索旋转排序数组
      • 方法一 二分查询最大最小值
      • 思路
      • 详解
      • 代码
      • 方法二 二分查询中间数
  • 在排序数组中查找元素的第一个和最后一个位置、数组中的第K个最大元素和颜色分类
    • 在排序数组中查找元素的第一个和最后一个位置
      • 方法一 二分查找
    • 数组中的第K个最大元素
      • 方法一
      • 方法二
      • 方法三
      • 题外话
    • 颜色分类
      • 方法一 直接计算
      • 方法二 双指针遍历
      • 方法三 使用各种排序法

搜索旋转排序数组

假设按照升序排序的数组在预先未知的某个点上进行了旋转。

( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。

搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。

你可以假设数组中不存在重复的元素。

你的算法时间复杂度必须是 O(log n) 级别。

示例 1:

输入: nums = [4,5,6,7,0,1,2], target = 0
输出: 4

示例 2:

输入: nums = [4,5,6,7,0,1,2], target = 3
输出: -1

方法一 二分查询最大最小值

思路

先算出 数组中最大最小值,利用 indexOf 计算之后要旋转位置,然后二分计算目标 target 位置

详解

  1. 计算数组中的最大最小值
  2. 定义变量,数组长度等
  3. 目标值大于数组最后一位时,数组查询位置从 0 到数字中在最大位置
  4. 目标值小于等于数组最后一位时,数组查询位置从数组中最小值的位置开始,到数组的最后一位,3.4 两部为了定位数组查询区间
  5. 循环二分查询,计算定位数组的中间值,数组的值等于目标查询结束
  6. 不等于的情况,如果目标大于中间值,则定位数组最小值等于中间值+1,目标小于中间值,则定位数组中最大值等于中间值-1,继续循环查询即可,知道定位数组查询完毕,没有结果的话,返回 -1 代表不存在

代码

const search = function (nums, target) {
  const min = Math.min.apply(null, nums);
  const max = Math.max.apply(null, nums);
  const len = nums.length;
  let pos;
  let lo;
  let hi;
  let mid;

  if (target > nums[len - 1]) {
    pos = nums.indexOf(max);
    lo = 0;
    hi = pos;
  } else {
    pos = nums.indexOf(min);
    lo = pos;
    hi = len - 1;
  }
  while (lo <= hi) {
    mid = Math.ceil((lo + hi) / 2);
    if (nums[mid] === target) return mid;
    if (nums[mid] < target) {
      lo = mid + 1;
    } else {
      hi = mid - 1;
    }
  }
  return -1;
};

复杂度分析:

  • 时间复杂度:O(log(n))O(log(n))

    过程会最多遍历一遍数组

  • 空间复杂度:O(1)O(1)

    只产生一次临时变量存储

方法二 二分查询中间数

思路

根据数组的中间数和左右节点的大小对比,来确定升序部分的位置,然后用二分法查询目标节点在数组中的位置

详解

  1. 计算数组长度,数组为0 直接返回-1
  2. 定义左右值分别为数组第一个和最后一个的下标
  3. 中间下标值为最大最小值的平均数
  4. 如果数组中间数等于目标直接返回下标
  5. 数组的中间值小于数组最后一个值,后半部分还处于升序,如果目标值在这部分数组中,则左下标等于中间值+1,代表目标值在后半部分数组,反着重新定义右下标为中间值-1,目标在前半数组
  6. 数组中间值大于数组最后一个值,代表前半部分数组处于升序,如果目标在前半数组中,右标更新为中间值-1,反之,左下标更新为中间值+1
  7. 二分查询到最后没找到目标值,则返回 -1 代表不存在

代码

const search = function(nums, target) {
  if(nums.length === 0){
    return -1;
  }

  let left = 0;
  let right = nums.length - 1;
  let mid;

  while(left <= right){
    mid = parseInt((left + right) / 2);
    if(nums[mid] === target){
      return mid;
    } else if(nums[mid] < nums[right]) {
      if(nums[mid] < target && target <= nums[right]) {
            left = mid + 1;
      } else {
        right = mid - 1;
      }
    } else {
      if(nums[left] <= target && target < nums[mid]){
            right = mid - 1;
      } else {
        left = mid + 1;
      }
    }
  }
  return -1;
};

复杂度分析

  • 时间复杂度:O(log(n))O(log(n))

    过程会最多遍历一遍数组

  • 空间复杂度:O(1)O(1)

    只产生一次临时变量存储

在排序数组中查找元素的第一个和最后一个位置、数组中的第K个最大元素和颜色分类

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

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

你的算法时间复杂度必须是 O(log n) 级别。

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

示例

输入: nums = [5,7,7,8,8,10], target = 8
输出: [3,4]

输入: nums = [5,7,7,8,8,10], target = 6
输出: [-1,-1]

方法一 二分查找

思路

由于数组已经时升序排列,可直接根据二分查找,往左定位第一个位置,往右定位最后一个位置 二分查找的实现上可以使用循环或者递归。

详解

  1. 根据二分查找,找到左边第一个不小于目标值的位置
  2. 从上一步中的位置开始到最后,二分查找,确定右边最后一个符合条件值的位置
  3. 得到结果
function getBinarySearchLowerBound (array, low, high, target) {
  // 找到第一个不小于目标值的位置
  while (low < high) {
    const mid = Math.floor((low + high) / 2);
    if (array[mid] < target) {
      low = mid + 1;
    } else {
      high = mid;
    }
  }

  // 如果相等,则匹配,否则不匹配
  return array[low] === target ? low : -1;
}

function getBinarySearchUpperBound (array, low, high, target) {
  // 找到第一个不大于目标值的位置
  while (low < high) {
    const mid = Math.ceil((low + high) / 2);
    if (array[mid] > target) {
      high = mid - 1;
    } else {
      low = mid;
    }
  }

  // 如果相等,则匹配,否则不匹配
  return array[high] === target ? high : -1;
}

const searchRange = function (nums, target) {
  const size = nums.length;
  const low = getBinarySearchLowerBound(nums, 0, size - 1, target);
  if (low === -1) {
    return [-1, -1];
  }
  // 从左边数字的位置开始
  const high = getBinarySearchUpperBound(nums, low >= 0 ? low : 0, size - 1, target);
  return [low, high];
};

复杂度分析

  • 时间复杂度:O(log(n))O(log(n))

    过程中最差情况会遍历二遍数组

  • 空间复杂度:O(1)O(1)

    产生三个临时变量存储

数组中的第K个最大元素

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例1:

输入: [3,2,1,5,6,4] 和 k = 2
输出: 5

示例2:

输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4

说明:你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。

方法一

思路

首先通过快速排序的方法将数组升序排序,此时数组的头部为最小的元素,尾部为数组最大的元素。题目要求找到数组中的第 K 个最大的元素,即返回 length - k 个元素即可。

详解

  1. 本方法采用快速排序法;
  2. 首先通过 arr[Math.floor((start + end) / 2)] 找到数组中间的元素作为主元;
  3. 然后使用双指针,分别从数组的头部和尾部遍历数组;
  4. 遍历过程中,把比主元小的数都放到主元的左边,比主元大的数都放到主元的右边,实现数组的升序排序;
  5. 返回第 length - k 个元素,即为数组中第 k 个最大的元素。

1

const findKthLargest = function (nums, k) {
  return findK(nums, 0, nums.length - 1, nums.length - k);
};

function findK (arr, start, end, k) {
  if (start === end) return arr[start];
  // 主元
  const pivot = arr[Math.floor((start + end) / 2)];
  let i = start; let j = end;
  while (i <= j) {
    while (arr[i] < pivot) i++;
    while (arr[j] > pivot) j--;
    if (i <= j) {
      swap(arr, i, j);
      i++;
      j--;
    }
  }
  // 二分查到k位置
  if (k >= (i - start)) {
    return findK(arr, i, end, k - i + start);
  } else {
    return findK(arr, start, i - 1, k);
  }
}
// 元素交换
function swap (arr, i, j) {
  const temp = arr[i];
  arr[i] = arr[j];
  arr[j] = temp;
}

复杂度分析

  • 时间复杂度: O(n log n)O(nlogn)

上述解法中,采用了快速排序的方法,快排的时间复杂度 O(n log n)O(nlogn)。

  • 空间复杂度: O(1)O(1)

上述解法中,申请了四个额外的临时存储空间,这将耗费 O(1)O(1) 的空间。

方法二

思路

首先通过最小堆排序的方法将数组升序排序,排序完的数组如下图所示:

image-20220807191400477

此时数组的头部为最小的元素,尾部为数组最大的元素。题目要求找到数组中的第 K 个最大的元素,即返回 length - k 个元素即可。

详解

  1. 本方法采用最小堆排序法;
  2. 首先建立最小堆,将每个叶子结点视为一个堆,再将每个叶子结点与其父节点一起构成一个包含更多结点的堆;
  3. 所以在构造堆的时候,首先需要找到最后一个结点的父节点,从这个节点开始构造最小堆,直到该节点前面的所有分支节点都处理完毕;
  4. 然后返回第 length - k 个,即为数组中第 k 个最大的元素。
const findKthLargest = function (nums, k) {
  const size = nums.length;
  // 建立堆
  for (let i = parseInt(size / 2) + 1; i >= 0; i--) {
    heapify(nums, i, size);
  }
  // 排序
  for (let j = size - 1; j >= size - k; j--) {
    // 得到本次的最大,将最大的与最后一个交换位子
    swap(nums, 0, j);
    heapify(nums, 0, j);
  }
  return nums[size - k];
};

function heapify (arr, x, length) {
  // 左右两个子节点
  const l = 2 * x + 1;
  const r = 2 * x + 2;
  let largest = x;
  if (l < length && arr[l] > arr[largest]) {
    largest = l;
  }
  if (r < length && arr[r] > arr[largest]) {
    largest = r;
  }
  if (largest !== x) {
    swap(arr, x, largest);
    // 递归交换以下的是否也建好堆.
    heapify(arr, largest, length);
  }
}

function swap (arr, i, j) {
  const temp = arr[i];
  arr[i] = arr[j];
  arr[j] = temp;
}

复杂度分析

  • 时间复杂度: O(n log n)O(nlogn)

上述解法中,采用了堆排序的方法,堆排序的时间复杂度 O(n log n)O(nlogn)。

  • 空间复杂度: O(1)O(1)

上述解法中,申请了四个额外的临时存储空间,这将耗费 O(1)O(1) 的空间。

方法三

思路

首先通过冒泡排序的方法将数组升序排序,此时数组的头部为最小的元素,尾部为数组最大的元素。题目要求找到数组中的第 K 个最大的元素,即返回 length - k 个元素即可。

详解

  1. 本方法采用经典冒泡排序法;
  2. 比较相邻的元素,如果第一个比第二个大,就交换他们两个;
  3. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对;
  4. 完成步骤 3 后,最后的元素会是最大的数,实现升序排序;
  5. 返回第 len-k 个元素,即为数组中第 k 个最大的元素。
const findKthLargest = function (nums, k) {
  const len = nums.length;
  for (let i = len - 1; i > 0; i--) {
    // 冒泡排序
    for (let j = 1; j <= i; j++) {
      // 异或交换,详见题外话解析
      if (nums[j - 1] > nums[j]) {
        nums[j - 1] ^= nums[j];
        nums[j] ^= nums[j - 1];
        nums[j - 1] ^= nums[j];
      }
    }
    if (i === (len - k)) {
      return nums[i];
    }
  }
  return nums[0];
};

复杂度分析

  • 时间复杂度: O(n^2)O(n2)

上述解法中,内外两层循环,时间复杂度 O(n^2)O(n2)。

  • 空间复杂度: O(1)O(1)

上述解法中,最优的情况是开始时元素已经按顺序排好,空间复杂度为 0 ,最差的情况是开始时元素逆序排序,此时空间复杂度 O(n)O(n),平均空间复杂度 O(1)O(1)。

复杂度分析:

  • 时间复杂度: O(n^2)O(n2),内外两层循环,时间复杂度 O(n^2)O(n2)
  • 空间复杂度: O(1)O(1),最优的情况是开始时元素已经按顺序排好,空间复杂度为0,最差的情况是开始时元素逆序排序,此时空间复杂度 O(n)O(n),平均空间复杂度 O(1)O(1)

题外话

对于给定两个整数a,b,下面的异或运算可以实现a,b的交换,而无需借助第3个临时变量:

a = a ^ b;
b = a ^ b;
a = a ^ b;

这个交换两个变量而无需借助第3个临时变量过程,其实现主要是基于异或运算的如下性质:

  1. 任意一个变量X与其自身进行异或运算,结果为0,即X ^ X=0
  2. 任意一个变量X与0进行异或运算,结果不变,即X ^ 0=X
  3. 异或运算具有可结合性,即a ^ b ^ c =(a ^ b)^ c= a ^( b ^ c)
  4. 异或运算具有可交换性,即a ^ b = b ^ a

分析:

第一步: a = a ^ b;

完成后 a变量的结果为a ^ b

第二步: b = a ^ b;

此时赋值号右边的 a 保存的是 a ^ b 的值,那么将赋值号右边的 a 用 a ^ b 替换,

得到(a ^ b) ^ b = a ^ (b ^ b)=a ^ 0=a,

即经过第二步运算后 b 中的值为 a ,即 b=a ,将 a 换到了 b 里

第三步: a = a ^ b;

此时赋值号右边的 a 保存的仍然是 a ^ b 的值,不变,而赋值号右边的 b 已经是 a 了,

将赋值号右边的 a,b 分别进行替换,

即此时赋值号右边 a ^ b=(a ^ b)^ a=a ^ b^ a=a ^ a^ b=0^ b=b, 该值赋值给 a ,即 a=b

即经过第三步运算后 a 中的值为 b ,即 a=b, 将 b 换到了 a 里

这样经过如上的三步骤,完成了交换两个变量 a,b 而无需借助第 3 个临时变量过程。

颜色分类

给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

注意: 不能使用代码库中的排序函数来解决这道题。

示例

输入: [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]

方法一 直接计算

思路

直接遍历整个数组,分别计算出红蓝白球的个数,然后按照红色、白色、蓝色顺序依次存入数组。

详解

  1. 设定三个变量 red, white,blue 分别表示红球、白球和蓝球。
  2. 遍历数组,遇到 0 则使 red 自增1,遇到 1 则使 white 自增1,遇到 2 则使 blue 自增1。
  3. 根据红白蓝的个数,依次将 0,1,2 存入数组。
/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
const sortColors = function (nums) {
  let red = 0;
  let blue = 0;
  let white = 0;
  for (let i = 0; i < nums.length; i++) {
    if (nums[i] === 0) {
      red++;
    } else if (nums[i] === 1) {
      blue++;
    } else if (nums[i] === 2) {
      white++;
    }
  }
  let index = 0;
  for (let i = 0; i < red; i++) {
    nums[index++] = 0;
  }
  for (let i = 0; i < blue; i++) {
    nums[index++] = 1;
  }
  for (let i = 0; i < white; i++) {
    nums[index++] = 2;
  }
};

复杂度分析

  • 时间复杂度: O(n)O(n)
  • 空间复杂度: O(n)O(n)

方法二 双指针遍历

思路

设定三个指针 begin, end, i,用 i 遍历数组,遇到 0,1 时分别将值与 begin, end 指向的值交换。这种方法相对于方法一的好处是只使用了一个常数空间。

详解

  1. 设定一头一尾两个指针 begin 和 end,然后用一个指针 i 从头开始遍历数组。
  2. 如果遇到 0,则将该数值与begin指向的值交换,并且使begin向后移一位。
  3. 如果遇到 2,则将该数值与end指向的值交换,并且使end向前移一位,并且此时不需自加 i
  4. 如果遇到 1,则继续。
  5. 最终得到新数组。
/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
const sortColors = function (nums) {
  let begin = 0;
  let end = nums.length - 1;
  let i = 0;
  while (i <= end) {
    if (nums[i] === 0) {
      nums[i] = nums[begin];
      nums[begin] = 0;
      i++;
      begin++;
    } else if (nums[i] === 2) {
      nums[i] = nums[end];
      nums[end] = 2;
      end--;
    } else {
      i++;
    }
  }
};

复杂度分析

  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(1)O(1)

方法三 使用各种排序法

思路

本题的实质是将数字从小到大排序,可以使用各种排序法(冒泡排序法,选择排序法,快速排序法等),这里举一个冒泡排序法的例子。

1

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
const sortColors = function (nums) {
  for (let i = 0; i < nums.length; i++) {
    for (let j = 0; j < nums.length - i; j++) {
      if (nums[j] > nums[j + 1]) {
        const tem = nums[j];
        nums[j] = nums[j + 1];
        nums[j + 1] = tem;
      }
    }
  }
};

复杂度分析

  • 时间复杂度:O(n^2)O(n2)

    遍历了两次含n个元素的空间

  • 空间复杂度:O(1)O(1)

    排序过程没有用到新的空间存储数据

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

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

相关文章

day-31 给植物浇水

思路 每次前进浇水时进行判断&#xff1a; &#xff08;1&#xff09;如果当前水足够&#xff0c;则前进一步浇水 &#xff08;2&#xff09;如果当前水量不够,则返回-1处加水再返回&#xff0c;再前进一步浇水 解题方法 用一个变量po记录即将浇水的植物编号&#xff0c;当pop…

05-09 周四 vLLM的部署和实践

05-09 周四 vLLM能够做什么事情 时间版本修改人描述2024年5月9日14:33:05V0.1宋全恒新建文档 简介 GitHub项目 vllm-project 官方网站上解释了Fast、和flexible and easy to use的原因。 注&#xff0c;如果要使用ModelScope中的模型&#xff0c;请设置环境变量&#xff1a; e…

深度学习——前馈全连接神经网络(鸢尾花)

前馈全连接神经网络对鸢尾花数据集进行分类 1.导入所需要的包2.打印训练集和测试集二维数组3.定义模型4.打印模型信息5.权重和偏执6.编译网络和训练网络7.打印二维数据表格8.绘制图像9.查看准确率 1.鸢尾花数据集可以用 from sklearn.datasets import load_iris 方式获取&#…

汽车行业芯片 车规级芯片 单车芯片( soc mcu)数量

链接&#xff1a;https://xueqiu.com/3000217281/272114755 10大车规级MCU芯片10大车规级MCU芯片 汽车芯片是什么&#xff1f; 汽车芯片即车规级芯片&#xff0c;标准要高于工业级和民用级芯片&#xff0c;仅次于军工级芯片。芯片大概有以下四种级别&#xff0c;分别是军工级…

基于OceanBase+Flink CDC,云粒智慧实时数仓演进之路

摘要&#xff1a;本文整理自云粒智慧高级技术专家付大伟在 4 月 20 日的 2024 OceanBase 开发者大会上的分享&#xff0c;讲述了其数据中台在传统数仓技术框架下做的一系列努力后&#xff0c;跨进 FlinkCDC 结合 OceanBase 的实时数仓演进过程。 内容主要分为以下几个部分: 业务…

2023年ICPC亚洲济南地区赛 G. Gifts from Knowledge

题目 思路&#xff1a; #include <bits/stdc.h> using namespace std; #define int long long #define pb push_back #define fi first #define se second #define lson p << 1 #define rson p << 1 | 1 const int maxn 1e6 5, inf 1e18, maxm 4e4 5, b…

一步一脚印式学习Linux第二课(简单明了)

继续昨天的基础命令&#xff0c;正文如下&#xff1a; 六、基础命令 8.history命令 作用&#xff1a;查看和控制历史记录 历史命令保存位置&#xff1a;~/.bash_history 启动终端时&#xff0c;会自动从历史命令保存位置的文件中读取历史命令加载到内存中。终端中执行命令时&…

视频降噪算法 hqdn3d 原理分析

视频降噪 视频降噪是一种处理技术&#xff0c;旨在减少视频中的噪声&#xff0c;提高画面质量。噪声可能来自多种源头&#xff0c;包括摄像机的传感器、压缩算法、传输过程中的干扰等。降噪处理对于视频监控、视频会议、电影后期制作以及任何需要高画质输出的应用场景都非常重…

msvcp110.dll是什么东西?关于msvcp110.dll丢失修复的问题分享

msvcp110.dll是什么东西&#xff1f;如果有人问出这个问题&#xff0c;那么百分之一百就是他遇到了丢失msvcp110.dll文件的问题了&#xff0c;不然别人是不可能问出这个问题的&#xff01;这个文件名字一般只有在你的电脑系统出现问题的时候&#xff0c;它才会弹出提示。今天来…

Baidu Comate智能编码助手

Baidu Comate智能编码助手 &#x1f388;1.Baidu Comate的简介&#x1f388;2.安装Baidu Comate&#x1f388;3.Baidu Comate实现功能&#x1f388;4.使用注释进行智能代码提示&#x1f388;5.结束语 &#x1f388;1.Baidu Comate的简介 根据官网的介绍&#xff0c;我们了解到B…

Verilog复习(一)| 模块的定义

模块&#xff08;module&#xff09;是Verilog的基本描述单位&#xff0c;用于描述某个设计的功能或结构&#xff0c;及其与其他模块通信&#xff08;连接&#xff09;的外部端口。 Verilog程序由关键词module和endmodule进行定义。 定义模块的步骤&#xff1a; 定义模块的端…

通用型产品发布解决方案(基础环境搭建)

文章目录 1.项目技术栈和前置技术2.创建Linux平台1.需求分析2.安装Virtual Box1.BIOS里修改设置开启虚拟化设备支持&#xff08;f2 或f10&#xff09;2.任务管理器 -> cpu 查看虚拟化是否开启3.卸载方式4.安装6.1.265.管理员身份运行&#xff0c;选择安装位置6.一直下一步&a…

Java基于Spring Boot框架毕业生实习与就业管理系统的设计与实现(附源码,说明文档)

博主介绍&#xff1a;✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3…

Qt---项目的创建及运行

一、创建第一个Qt程序 1. 点击创建项目后&#xff0c;选择项目路径以及给项目起名称 名称&#xff1a;不能有中文、不能有空格 路径&#xff1a;不能有中文路径 2. 默认创建有窗口类myWidget&#xff0c;基类有三种选择&#xff1a;QWidget、QMainWindow、QDialog 3. m…

智慧手术室手麻系统源码,C#手术麻醉临床信息系统源码,符合三级甲等医院评审要求

手麻系统全套源码&#xff0c;C#手术麻醉系统源码&#xff0c;支持二次开发&#xff0c;授权后可商用。 手术麻醉临床信息系统功能符合三级甲等医院评审要求&#xff0c;实现与医院现有信息系统如HIS、LIS、PACS、EMR等系统全面对接&#xff0c;全面覆盖从患者入院&#xff0c;…

深度学习之视觉特征提取器——GoogleNet/Inception

GoogleNet GoogleNet在2014年中的ImageNet夺冠&#xff0c;将Inception这一结构推向了热潮。从另外一个角度来看&#xff0c;CV魔改网络结构也从中得到启发或者说推动&#xff0c;拓宽了各种魔改的方式。GoogleNet其实只是Inception这一结构大规模集成后得到的模型&#xff0c…

堆的应用1——堆排序

一&#xff0c;堆排序 堆排序是一种基于比较的排序算法&#xff0c;它利用堆这种数据结构所设计。 堆是一个近似完全二叉树的结构&#xff0c;并同时满足堆积的性质&#xff1a;即子结点的键值或索引总是小于&#xff08;或者大于&#xff09;它的父结点。 堆排序可以分为两…

【python】模拟巴特沃斯滤波器

巴特沃斯滤波器&#xff08;Butterworth Filter&#xff09;&#xff0c;以其设计者斯蒂芬巴特沃斯&#xff08;Stephen Butterworth&#xff09;的名字命名&#xff0c;是一种具有平滑频率响应的滤波器。这种滤波器在频域中具有非常平坦的无波纹响应&#xff0c;直到它达到截止…

Linux(openEuler、CentOS8)企业内网DHCP服务器搭建(固定Mac获取指定IP)

----本实验环境为openEuler系统<以server方式安装>&#xff08;CentOS8基本一致&#xff0c;可参考本文&#xff09;---- 目录 一、知识点二、实验&#xff08;一&#xff09;为服务器配置网卡和IP&#xff08;二&#xff09;为服务器安装DHCP服务软件&#xff08;三&a…

iOS 17 / iPad OS 17屏蔽更新

iOS 17 / iPad OS 17屏蔽更新 1&#xff0c;进入屏蔽iOS更新的描述文件下载链接 下载链接 wx 搜索 Geek 前端发送屏蔽更新进行获取 2&#xff0c;复制这段链接&#xff0c;在Safari浏览器中打开&#xff0c;注意打开后别点击下载&#xff01;要先改时间&#xff01; 3&#…