【面试题】20个常见的前端算法题,你全都会吗?

news2024/9/24 15:25:58

现在面试中,算法出现的频率越来越高了,大厂基本必考

今天给大家带来20个常见的前端算法题,重要的地方已添加注释,如有不正确的地方,欢迎多多指正💕

 大厂面试题分享 面试题库

前后端面试题库 (面试必备) 推荐:★★★★★

地址:前端面试题库  web前端面试题库 VS java后端面试题库大全

1、两数之和

题目: 给定一个数组 nums 和一个目标值 target,在该数组中找出和为目标值的两个数

输入: nums: [8, 2, 6, 5, 4, 1, 3] ; target:7

输出: [2, 5]

// 时间复杂度O(n)、 空间复杂度O(n)
function twoNumAdd(arr, target) {
  if (Array.isArray(arr)) {
    // 使用map将遍历过的数字存起来,空间换时间
    let map = {};
    for (let i = 0; i < arr.length; i++) {
      // 从map中查找是否有key 等于 target-nums[i],如果有,则条件成立,返回结果
      if (map[target - arr[i]] !== undefined) {
        return [target - arr[i], arr[i]];
      } else {
        // 条件不成立,将该值存起来
        map[arr[i]] = i;
      }
    }
  }
  return [];
}
复制代码

2、三数之和

题目: 给定一个数组nums,判断 nums 中是否存在三个元素a,b,c,使得 a + b + c = target,找出所有满足条件且不重复的三元组合

输入: nums: [5, 2, 1, 1, 3, 4, 6] ;target:8

输出: [[1, 1, 6], [1, 2, 5], [1, 3, 4]]

// 用`双端指针`的方式,将三数之和转化为两数之和
function findThree(arr, target) {
  // 先将数组从小到大排序
  arr.sort((a, b) => a - b))
  let result = [];
  for (let i = 0; i < arr.length; i++) {
    // 跳过重复的arr[i]值, 比如[2, 1, 1],跳过第二个1
    if (i && arr[i] === arr[i - 1]) continue;
    let left = i + 1;
    let right = arr.length - 1;
    
    // 双端指针left、right
    while (left < right) {
      let sum = arr[i] + arr[left] + arr[right];
      if (sum > target) {
        right--;
      } else if (sum < target) {
        left++;
      } else {
        // 先取arr[left],然后left++, 两步合成一步;arr[right--]同样的逻辑
        result.push([arr[i], arr[left++], arr[right--]]);
        while (arr[left] === arr[left - 1]) {
          // 跳过重复的arr[left]值,
          left++;
        }
        while (arr[right] === arr[right + 1]) {
          // 跳过重复的arr[right]值
          right--;
        }
      }
    }
  }
  return result;
}
复制代码

3、版本号排序

题目: 输入一组版本号,输出从大到小的排序

输入: ['2.1.0.1', '0.402.1', '10.2.1', '5.1.2', '1.0.4.5']

输出: ['10.2.1', '5.1.2', '2.1.0.1', '1.0.4.5', '0.402.1']

function versionSort(arr) {
  return arr.sort((a, b) => {
    let i = 0;
    const arr1 = a.split(".");
    const arr2 = b.split(".");
    while (true) {
      // 取出相同位置的数字
      const s1 = arr1[i];
      const s2 = arr2[i];
      i++;
      // 若s1 或 s2 不存在,说明相同的位置已比较完成,接下来比较arr1 与 arr2的长度,长的版本号大
      if (s1 === undefined || s2 === undefined) {
        return arr2.length - arr1.length;
      }
      if (s1 === s2) continue;
      // 比较相同位置的数字大小
      return s2 - s1;
    }
  });
}
复制代码

4、第一个不重复的字符

题目: 输入一个字符串,找到第一个不重复字符的下标

输入: 'abcabcde'

输出: 6

// 时间复杂度O(n)、 空间复杂度O(n)
function findOneStr(str) {
  if (!str) return -1;
  // 使用map存储每个字符出现的次数
  let map = {};
  let arr = str.split("");
  arr.forEach(item => {
    let val = map[item];
    // val为undefined时,表示未存储,map[item] = 1;否则map[item] = val + 1
    map[item] = val ? val + 1 : 1;
  });
  // 再遍历一遍找到出现1次的下标
  for (let i = 0; i < arr.length; i++) {
    if (map[arr[i]] == 1) {
      return i;
    }
  }
  return -1;
}
复制代码

5、字符串所有排列组合

题目: 输入一个字符串,打印出该字符串中,所有字符的排列组合

输入: 'abc'

输出: ['abc', 'acb', 'bca', 'bac', 'cab', 'cba']

/**
 * 利用回溯算法,计算所有字符串的组合
 * @param {array} list - 字符串列表
 * @param {array} result - 最终的结果
 * @param {string} current - 当前的字符串
 * @param {string} temp - 当前固定的字符
*/
function stringGroup(list = [], result = [], current = "", temp = "") {
  current += temp;
  if (list.length === 0) {
    // 递归的出口,将对应结果添加到list中
    return result.push(current);
  }
  for (let i = 0; i < list.length; i++) {
    // 每次递归 固定第一个字符
    temp = list.shift();
    stringGroup(list, result, current, temp);
    // 将删除的temp重新添加到queue尾部,实现将数组反转的效果,如[a,b,c]反转为[c,b,a]
    list.push(temp);
  }
  // 这里去重是解决str中有重复的字母,比如str为'aacd'
  return [...new Set(result)];
}
复制代码

6、冒泡排序

时间复杂度为O(n²),稳定排序算法

function bubbleSort(arr) {
  let length = arr.length;
  // 外层循环用控制 排序进行多少轮
  for (let i = 0; i < length; i++) {
    // 内层循环用于每一轮的数据比较
    // 注意j的长度范围 length - i - 1
    for (let j = 0; j < length - i - 1; j++) {
      // 相邻元素,大的放到后面
      if (arr[j] > arr[j + 1]) {
        // 交换位置
        [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
      }
    }
  }
  return arr;
}
复制代码

7、选择排序

时间复杂度为O(n²),不稳定

function selectSort(arr) {
  // 定义index存储最小值的下标
  let index;
  // 外层循环用控制 排序进行多少轮
  for (let i = 0; i < arr.length - 1; i++) {
    index = i;
    // 内层循环用于每一轮的数据比较
    // 注意j的起始范围是 i + 1
    for (let j = i + 1; j < arr.length; j++) {
      // 寻找最小值
      if (arr[j] < arr[index]) {
        // 保存最小值的下标
        index = j;
      }
    }
    // 如果 index 不是目前的头部元素,则交换两者
    if (index !== i) {
      [arr[i], arr[index]] = [arr[index], arr[i]];
    }
  }
  return arr;
}
复制代码

8、插入排序

时间复杂度为O(n²),稳定

function insertSort(arr) {
  // 从第 2 个元素开始遍历序列
  for (let i = 1; i < arr.length; i++) {
    let j = i;
    //记录要插入的目标元素
    let target = arr[j];
    //从 target 所在位置向前遍历,直至找到一个比目标元素小的元素,目标元素插入到该元素之后的位置
    while (j > 0 && arr[j - 1] > target) {
      //移动前一个元素的位置,将其向后移动一个位置
      arr[j] = arr[j - 1];
      j--;
    }
    arr[j] = target;
  }
  return arr;
}
复制代码

9、快速排序

时间复杂度为O(nlogn),不稳定

function quickSort(list) {
  // 当list.length <= 1时,退出递归
  if (list.length <= 1) return list;
  // 找到中间节点
  let mid = Math.floor(list.length / 2);
  // 以中间节点为基准点,比该节点大的值放到right数组中,否则放到left数组中
  let base = list.splice(mid, 1)[0];
  let left = [];
  let right = [];
  list.forEach(item => {
    if (item > base) {
      right.push(item);
    } else {
      left.push(item);
    }
  });
  // 重新组合数组
  return quickSort(left).concat(base, quickSort(right));
}
复制代码

10、归并排序

时间复杂度为O(nlogn),稳定

function MergeSort(array) {
  let len = array.length;

  // 当每个子序列中仅有1个元素时返回
  if (len <= 1) {
    return array;
  }
  // 将给定的列表分为两半
  let num = Math.floor(len / 2);
  let left = MergeSort(array.slice(0, num));
  let right = MergeSort(array.slice(num, array.length));
  return merge(left, right);

  function merge(left, right) {
    let [l, r] = [0, 0];
    let result = [];
    // 从 left 和 right 区域中各个取出第一个元素,比较它们的大小
    while (l < left.length && r < right.length) {
      // 将较小的元素添加到result中,然后从较小元素所在的区域内取出下一个元素,继续进行比较;
      if (left[l] < right[r]) {
        result.push(left[l]);
        l++;
      } else {
        result.push(right[r]);
        r++;
      }
    }
    // 如果 left 或者 right 有一方为空,则直接将另一方的所有元素依次添加到result中
    result = result.concat(left.slice(l, left.length));
    result = result.concat(right.slice(r, right.length));
    return result;
  }
}
复制代码

11、列表转成树

题目: 输入一组列表如下,转化成树形结构

输入

[
  { id: 1, title: "child1", parentId: 0 },
  { id: 2, title: "child2", parentId: 0 },
  { id: 3, title: "child1_1", parentId: 1 },
  { id: 4, title: "child1_2", parentId: 1 },
  { id: 5, title: "child2_1", parentId: 2 }
]
复制代码

输出

tree=[
  {
    "id": 1,
    "title": "child1",
    "parentId": 0,
    "children": [
      {
        "id": 3,
        "title": "child1_1",
        "parentId": 1
      },
      {
        "id": 4,
        "title": "child1_2",
        "parentId": 1
      }
    ]
  },
  {
    "id": 2,
    "title": "child2",
    "parentId": 0,
    "children": [
      {
        "id": 5,
        "title": "child2_1",
        "parentId": 2
      }
    ]
  }
]
复制代码
function listToTree(data) {
  // 使用对象重新存储数据, 空间换时间
  let map = {};
  // treeData存储最后结果
  let treeData = [];
  // 遍历原始数据data,存到map中,id为key,值为数据
  for (let i = 0; i < data.length; i++) {
    map[data[i].id] = data[i];
  }
  // 遍历对象
  for (let i in map) {
    // 根据 parentId 找到的是父节点
    if (map[i].parentId) {
      if (!map[map[i].parentId].children) {
        map[map[i].parentId].children = [];
      }
      // 将子节点放到父节点的 children中
      map[map[i].parentId].children.push(map[i]);
    } else {
      // parentId 找不到对应值,说明是根结点,直接插到根数组中
      treeData.push(map[i]);
    }
  }
  return treeData;
}
复制代码

12、深度优先遍历

题目: 对树进行遍历,从第一个节点开始,遍历其子节点,直到它的所有子节点都被遍历完毕,然后再遍历它的兄弟节点

输入: 上文第11题生成的tree

输出: [1, 3, 4, 2, 5]

// 递归版本
function deepTree(tree, arr = []) {
  if (!tree || !tree.length) return arr;
  tree.forEach(data => {
    arr.push(data.id);
    // 遍历子树
    data.children && deepTree(data.children, arr);
  });
  return arr;
}

// 非递归版本
function deepTree(tree) {
  if (!tree || !tree.length) return;
  let arr = [];
  let stack = [];
  //先将第一层节点放入栈
  for (let i = 0, len = tree.length; i < len; i++) {
    stack.push(tree[i]);
  }
  let node;
  while (stack.length) {
    // 获取当前第一个节点
    node = stack.shift();
    arr.push(node.id);
    //如果该节点有子节点,继续添加进入栈顶
    if (node.children && node.children.length) {
      stack = node.children.concat(stack);
    }
  }
  return arr;
}
复制代码

13、广度优先遍历

题目: 以横向的维度对树进行遍历,从第一个节点开始,依次遍历其所有的兄弟节点,再遍历第一个节点的子节点,一层层向下遍历

输入: 上文第11题生成的tree

输出: [1, 2, 3, 4, 5]

function rangeTree(tree) {
  if (!tree || !tree.length) return;
  let arr = [];
  let node, list = [...tree];
  // 取出当前节点
  while ((node = list.shift())) {
    arr.push(node.id);
    node.children && list.push(...node.children);
  }
  return arr;
}
复制代码

14、树形结构查找节点

题目: 查找树形结构中符合要求的节点

输入
tree: 上文第11题生成的tree
func: data => data.title === "child2_1"

输出:{ id: 5, parentId: 2, title: "child2_1" }

/**
* 查找节点
* @param {array} tree - 树
* @param {function} func - 查找条件
* */
function findTreeNode(tree, func) {
  for (const data of tree) {
    // 条件成立 直接返回
    if (func(data)) return data;
    if (data.children) {
      const res = findTreeNode(data.children, func);
      // 结果存在再返回
      if (res) return res;
    }
  }
  return null;
}
// 测试
findTreeNode(tree, data => data.title === "child2_1")
复制代码

15、二叉查找树

题目: 判断一个数组,是否为某二叉查找树的前序遍历结果,二叉查找树特点是所有的左节点比父节点的值小,所有的右节点比父节点的值大

输入: [5, 3, 2, 1, 4, 6, 7, 8, 9]

输出: true

function preOrderOfBST(list) {
  if (list && list.length > 0) {
    // 前序遍历,第一个值为根节点
    var root = list[0];
    // 找到数组中,第一个比根节点大的节点,即为右子树的节点
    for (var i = 0; i < list.length; i++) {
      if (list[i] > root) {
        break;
      }
    }
    // 遍历右子树的节点,要求所有右子树的节点都比根节点大
    for (let j = i; j < list.length; j++) {
      if (list[j] < root) {
        return false;
      }
    }
    var left = true;
    // 同理,递归判断左子树是否符合二叉查找树的规则
    if (i > 1) {
      left = preOrderOfBST(list.slice(1, i + 1));
    }
    var right = true;
    // 递归判断右子树是否符合二叉查找树的规则
    if (i < list.length) {
      right = preOrderOfBST(list.slice(i, list.length));
    }
    // 左、右子树都符合要求,则是一个二叉查找树
    return left && right;
  }
}
复制代码

16、查找二叉树的路径

题目: 查找二叉树和为某一值的路径

输入: 二叉树结构如下,找到和为 11 的所有路径

输出: [[5, 3, 2, 1], [5, 6]]

/**
* 利用回溯算法,找到和为某一值的路径
* @param {object} node - 二叉树
* @param {number} num - 目标值
* @param {array} stack - 栈
* @param {number} sum - 当前路径的和
* @param {array} result - 存储所有的结果
* */
function findPath(node, num, stack = [], sum = 0, result = []) {
  stack.push(node.data);
  sum += node.data;

  // 找到所有的节点路径(包含叶子节点和子节点的所有情况之和)
  if (sum === num) {
    // if (!node.left && !node.right && sum === num) {  // 找到所有的叶子节点路径
    result.push(stack.slice());
  }
  if (node.left) {
    findPath(node.left, num, stack, sum, result);
  }
  if (node.right) {
    findPath(node.right, num, stack, sum, result);
  }
  // 回溯算法:不符合要求,退回来,换一条路再试
  // 叶子节点直接pop;子节点中的所有的节点递归完成后再pop
  stack.pop();
  return result;
}
复制代码

17、买卖股票问题

题目: 给定一个整数数组,其中第 i 个元素代表了第 i天的股票价格;
非负整数 fee 代表了交易股票的手续费用,求返回获得利润的最大值

输入: arr: [1, 12, 13, 9, 15, 8, 6, 16]; fee: 2

输出: 22

/**
 * 贪心算法求解
 * @param {array} list - 股票每天的价格列表
 * @param {number} fee - 手续费
 * */
function buyStock(list, fee) {
  // min为当前的最小值,即买入点
  let min = list[0],
    sum = 0;
  for (let i = 1; i < list.length; i++) {
    // 从1开始,依次判断
    if (list[i] < min) {
      // 寻找数组的最小值
      min = list[i];
    } else {
      // 计算如果当天卖出是否赚钱
      let temp = list[i] - min - fee;
      if (temp > 0) {
        // 赚钱 存数据
        sum += temp;
        // 关键代码:重新计算min,分两种情况,如果后面继续涨,则默认继续持有;若后面跌,则以后面的价格重新买入
        min = list[i] - fee;
      }
    }
  }
  return sum;
}
复制代码

18、斐波那契数列

题目: 从第3项开始,当前项等于前两项之和: 1 1 2 3 5 8 13 21 ……,计算第n项的值

输入: 10

输出: 89

// 使用动态规划,将复杂的问题拆分,也就是:`F(N) = F(N - 1) + F(N - 2)`,用数组将已经计算过的值存起来
function fib(n) {
  // 使用dp数组,将之前计算的结果存起来,防止栈溢出
  if (n < 2) return 1;
  let dp = [1, 1];
  for (let i = 2; i <= n; i++) {
    dp[i] = dp[i - 1] + dp[i - 2];
  }
  return dp[n - 1];
}
复制代码

19、滑动窗口最大值

题目: 给定一个数组 nums,有一个大小为 k 的滑动窗口,从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口中的k个数字。滑动窗口每次只向右移动一位,求返回滑动窗口最大值

输入: nums: [1,3,-1,-3,5,3,6,7]; k: 3

输出: [3, 3, 5, 5, 6, 7]

function maxSlidingWindow(nums, k) {
  // window存储当前窗口中数据的下标
  const window = [];
  // result存储窗口中的最大值
  const result = [];
  for (let i = 0; i < nums.length; i++) {
    if (i - window[0] > k - 1) {
      // 剔除窗口长度超出范围时左侧的最大值
      window.shift(); 
    }
    for (let j = window.length - 1; j >= 0; j--) {
      // 当前窗口的值依次和要插入的值做比较,如果小于要插入的值,剔除掉该值,直到window为空为止(保证window中最左侧的值为最大值)
      if (nums[window[j]] <= nums[i]) {
        window.pop();
      }
    }
    // 添加右侧新加入的值,插入新值时有两种情况:
    // 1、新值为最大值时,则window此时为空;
    // 2、新值不为最大值时,window已剔除掉比新值小的值
    window.push(i);
    if (i >= k - 1) {
      // 窗口是从0开始移动,当移动的距离大于等于目标范围后,以后再往后移动一次,就要写入当前窗口的最大值
      result.push(nums[window[0]]);
    }
  }
  return result;
}
复制代码

20、最长递增子序列

题目: 一个整数数组 nums,找到其中一组最长递增子序列的值

输入: [3,5,7,1,2,8]

输出: [3,5,7,8]

function lengthOfLIS(nums) {
  if (!nums.length) return 0;
  // 创建一个和原数组等长的数组dp,用来存储每一项的最长递增子序列
  // 比如[1,2,2] 表示第二项和第三项的最长递增子序列都为2
  let dp = new Array(nums.length).fill(1);
  // 双层for循环,每一项都和之前的所有项一一进行比较,计算出该项的最长递增子序列个数,存储到dp中
  for (let i = 0; i < nums.length; i++) {
    // 当前项依次和之前的每一项进行比较,累加出当前项的最长递增子序列
    for (let j = 0; j < i; j++) {
      if (nums[j] < nums[i]) {
        // 比较当前项已有的最大值和之前项最大值,比如当比较到第三项[1,2,2]时,如第三项比第二项大,所以第三项的计算结果为[1,2,3]
        dp[i] = Math.max(dp[i], dp[j] + 1);
      }
    }
  }
  // 取出一组最长递增子序列的具体值(注意:最长递增子序列有可能有多组值,这里是只取出其中一组值)
  // 找到dp中的最大值,该值就是nums的最长递增子序列的个数
  let max = Math.max(...dp);
  let result = [];
  for (let i = max; i >= 1; i--) {
    // 倒序遍历,根据长度获取对应的值
    findArrNode(dp, i, result, nums);
  }
  return result;
}
function findArrNode(dp, value, result, arr) {
  // 找到符合条件最后一项的下标,这样才能保证数组的顺序是正确的
  let index = dp.lastIndexOf(value);
  // 存储对应的值
  result.unshift(arr[index]);
  // 对dp进行截取,保证只取最大项之前的数据
  dp.length = index + 1;
}

 

大厂面试题分享 面试题库

前后端面试题库 (面试必备) 推荐:★★★★★

地址:前端面试题库  web前端面试题库 VS java后端面试题库大全

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

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

相关文章

Spring 6 正式“抛弃”feign

近期&#xff0c;Spring 6 的第一个 GA 版本发布了&#xff0c;其中带来了一个新的特性——HTTP Interface。这个新特性&#xff0c;可以让开发者将 HTTP 服务&#xff0c;定义成一个包含特定注解标记的方法的 Java 接口&#xff0c;然后通过对接口方法的调用&#xff0c;完成 …

Simulink仿真封装中的参数个对话框设置

目录 参数和对话框窗格 初始化窗格 文档窗格 为了更加直观和清晰的分析仿真&#xff0c;会将多个元件实现的一个功能封装在一起&#xff0c;通过参数对话框窗格&#xff0c;可以使用参数、显示和动作选项板中的对话框控制设计封装对话框。如图所示&#xff1a; 参数和对话框…

刘二大人《Pytorch深度学习实践》第六讲逻辑斯蒂回归

文章目录线性回归和逻辑斯蒂回归的区别课上代码交叉熵函数的理解线性回归和逻辑斯蒂回归的区别 线性回归一般用于预测连续值变量&#xff0c;如房价预测问题。 线性回归的一般表达式为&#xff1a; 代价函数为MSE&#xff08;均方误差&#xff09;&#xff1a; 其中权重thet…

Linux Shell 实现一键部署二进制Rabbitmq

rabbitmq 前言 RabbitMQ是实现了高级消息队列协议&#xff08;AMQP&#xff09;的开源消息代理软件&#xff08;亦称面向消息的中间件&#xff09;。RabbitMQ服务器是用Erlang语言编写的&#xff0c;而集群和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代…

openai的whisper语音识别介绍

openAI发布了chatgpt&#xff0c;光环一时无两。但是openAI不止有这一个项目&#xff0c;它的其他项目也非常值得我们去研究学习。 今天说说这个whisper项目 https://github.com/openai/whisper ta是关于语音识别的。它提出了一种通过大规模的弱监督来实现的语音识别的方法。…

C++之深入解析STL unordered_map的底层实现原理

C STL 标准库中&#xff0c;不仅是 unordered_map 容器&#xff0c;所有无序容器的底层实现都采用的是哈希表存储结构。更准确地说&#xff0c;是用“链地址法”&#xff08;又称“开链法”&#xff09;解决数据存储位置发生冲突的哈希表&#xff0c;整个存储结构如下所示&…

JVM 垃圾收集器详解

一、垃圾收集器 如果说收集算法是内存回收的方法论&#xff0c;那垃圾收集器就是内存回收的实践者。《Java虚拟机规范》中对垃圾收集器应该如何实现并没有做出任何规定&#xff0c;因此不同的厂商、不同版本的虚拟机所包含的垃圾收集器都可能会有很大差别&#xff0c;不同的虚…

基于遗传算法的中药药对挖掘系统的设计与实现

用数据挖掘技术研究了中药方剂配伍的规律。主要工作&#xff1a;分析了关联规则存在的问题&#xff0c;引入双向关联规则的概念&#xff1b;介绍了遗传算法的基本原理&#xff0c;研究了遗传算法在数据挖掘中的应用&#xff1b;将方剂库转换为位图矩阵&#xff0c;大大提高搜索…

Mac重启清理缓存会怎么样 mac清理缓存怎么清理

众所周知&#xff0c;Mac电脑有着流畅的操作系统&#xff0c;因此&#xff0c;很多用户都会选择使用Mac电脑办公。随着日常使用&#xff0c;系统缓存数据越来越大&#xff0c;某些Mac电脑&#xff08;尤其是小内存版本的Mac电脑&#xff09;可能会出现“系统”占存储空间比例较…

初始单片机.md

1.如何将HEX文件烧录到单片机 STC-ISP STC-ISP是一款单片机下载编程烧录软件&#xff0c;是针对STC系列单片机而设计的&#xff0c;可下载STC89系列、12C2052系列和12C5410等系列的STC单片机&#xff0c;使用简便。 思路&#xff1a;将电脑磁盘上已存在的文件通过串口的方式下…

python中第三方库xlrd和xlwt的使用教程

excel文档名称为联系人.xls&#xff0c;内容如下&#xff1a; 一、xlrd模块用法 1.打开excel文件并获取所有sheet import xlrd# 打开Excel文件读取数据 data xlrd.open_workbook(联系人.xls)sheet_name data.sheet_names() # 获取所有sheet名称 print(sheet_name) # [银…

python依次运行多个代码遇到的同步与异步问题

1、要实现在一个Python代码运行完后紧接着运行另一个Python代码&#xff0c;可以使用Python的subprocess模块。该模块可以创建新进程并与之交互&#xff0c;可以用于在Python代码中启动新的程序或脚本。 下面是一个示例代码&#xff0c;用于在运行完code1.py后紧接着运行code2…

论文配色方案(收藏)

方案一&#xff1a;复古 系列色——十六进制颜色码&#xff1a; 0780cf - 765005 - fa6d1d - 0e2c82 - b6b51f - da1f18 - 701866 - f47a75 - 009db2 - 024b51 - 0780cf - 765005 系列色——RGB颜色值&#xff1a; &#xff08;7,128,207&#xff09;-&#xff08;118,80,5&…

【记录】优化油猴插件【BD网盘播放器】

收获最重要前言优化代码收获1.禁止浏览器弹窗2.定时器3.设置属性-隐藏元素4.鼠标悬停和移开事件5.添加元素6.div里均匀分布7.获取元素属性值8.监听播放器状态9.jQuery 选择器前言 有钱的可以支持一下原作者&#xff0c;没钱就要多学习 优化 1.1 视频刚开始未播放时&#xff…

酷雷曼一站式图片直播,助力品牌高效传播

传统模式下&#xff0c;摄影师拍摄会议、活动现场的照片后&#xff0c;一般需要7-10天时间才能完成成片交付&#xff0c;而实际上&#xff0c;由于新闻宣传的即时性&#xff0c;照片延迟交付&#xff0c;远远不能满足客户的需求。因此&#xff0c;即时图片直播技术应运而生&…

Jenkins自动化部署实例讲解

文章目录 前言实例讲解基本环境全局工具配置创建任务任务配置源码管理构建步骤&#xff08;Build Steps&#xff09;第一步&#xff1a;调用Maven第二步&#xff1a;执行shell启动容器 后记 前言 你平常在做自己的项目时&#xff0c;是否有过部署项目太麻烦的想法&#xff1f;…

哈希应用——位图(bitset)

目录 见见猪跑(初步了解位图) 位图的模拟实现 位图的应用 1、给定100亿个整数&#xff0c;设计算法找到只出现一次的整数 2、给两个文件&#xff0c;分别有100亿个整数&#xff0c;我们只有1G内存&#xff0c;如何找到两个文件交集&#xff1f; 3、位图应用变形&#xff…

第六章 Gated RNN

目录6.1 RNN的问题6.1.1 RNN的复习6.1.2 梯度消失和梯度爆炸6.1.3 梯度消失和梯度爆炸的原因6.1.4 梯度爆炸的对策6.2 梯度消失和LSTM6.2.1 LSTM的接口6.2.2 LSTM层的结构6.2.3 输出门6.2.4 遗忘门6.2.5 新的记忆单元6.2.6 输入门6.2.7 LSTM的梯度的流动6.3 LSTM的实现6.4 使用…

CIO成就计划第二季第一期 | 活动回顾:基于数字技术重塑流程,驱动业务增长

2023年3月25日&#xff0c;《科创人》联手金蝶共同打造的【CIO成就计划第二季】首期培训在北京金蝶软件园圆满举行。 【CIO成就计划】第二季&#xff0c;坚持服务于企业CIO、数字化变革负责人的价值定位&#xff0c;通过三期线下闭门培训会社群交流&#xff0c;帮助CIO建立应对…

JUC高级十-AbstractQueuedSynchronizer之AQS

1. 前置知识 公平锁和非公平锁可重入锁自旋锁LockSupport数据结构之双向链表设计模式之模板设计模式 AQS重要性 JAVA ------>JVM AQS ------>AQS 2. AQS入门级别理论知识 2.1 是什么? 2.1.1 字面意思 Abstract Queued Synchronizer----抽象的队列同步器 源码位置: …