代码随想录 二叉树第五周

目录

235.二叉搜索树的最近公共祖先

701.二叉搜索树的插入操作

450.删除二叉搜索树中的节点

 669.修建二叉搜索树

108.将有序数组转换为二叉搜索树

538.把二叉搜索树转换为累加树


235.二叉搜索树的最近公共祖先

235. 二叉搜索树的最近公共祖先

中等

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉搜索树:  root = [6,2,8,0,4,7,9,null,null,3,5]

示例 1:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6 
解释: 节点 2 和节点 8 的最近公共祖先是 6。

示例 2:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。

说明:

  • 所有节点的值都是唯一的。
  • p、q 为不同节点且均存在于给定的二叉搜索树中。

如果 中间节点是 q 和 p 的公共祖先,那么 中节点的数组 一定是在 [p, q]区间的。即 中节点 > p && 中节点 < q 或者 中节点 > q && 中节点 < p。

那么只要从上到下去遍历,遇到 cur节点是数值在[p, q]区间中则一定可以说明该节点cur就是p 和 q的公共祖先。 

如图,我们从根节点搜索,第一次遇到 cur节点是数值在[q, p]区间中,即 节点5,此时可以说明 q 和 p 一定分别存在于 节点 5的左子树,和右子树中。

235.二叉搜索树的最近公共祖先

此时节点5是不是最近公共祖先? 如果 从节点5继续向左遍历,那么将错过成为p的祖先, 如果从节点5继续向右遍历则错过成为q的祖先。

所以当我们从上向下去递归遍历,第一次遇到 cur节点是数值在[q, p]区间中,那么cur就是 q和p的最近公共祖先。

/**  * Definition for a binary tree node.  * 定义了一个二叉树的节点类。  * public class TreeNode {  *     int val;        // 节点的值  *     TreeNode left;  // 指向左子节点的指针  *     TreeNode right; // 指向右子节点的指针  *     TreeNode(int x) { val = x; } // 构造函数,用于创建一个新节点,并设置其值为x  * }  */  class Solution {  // 在二叉搜索树中找到节点p和q的最低公共祖先  public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {  // 如果根节点为空,表示当前子树不包含p和q,返回null  if(root == null){  return null;  }  // 如果根节点的值大于p和q的值,说明p和q(如果存在)一定在左子树中  if(root.val > p.val && root.val > q.val){  // 递归地在左子树中查找p和q的最低公共祖先  TreeNode leftResult = lowestCommonAncestor(root.left,p,q);  return leftResult;  }  // 如果根节点的值小于p和q的值,说明p和q(如果存在)一定在右子树中  if(root.val < p.val && root.val < q.val){  // 递归地在右子树中查找p和q的最低公共祖先  TreeNode rightResult = lowestCommonAncestor(root.right,p,q);  return rightResult;  }  // 如果根节点的值位于p和q的值之间,说明p和q分别位于根节点的左右两侧  // 因此,当前根节点就是p和q的最低公共祖先  return root;  }  
}

 迭代法:

class Solution {  // 定义Solution类  public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {  // 定义方法lowestCommonAncestor,接收三个参数:BST的根节点root,以及要查找的两个节点p和q  while(root != null){  // 当根节点不为null时,进行循环查找  if(root.val > p.val && root.val > q.val){  // 如果当前根节点的值大于p和q的值  root = root.left;  // 则最低公共祖先一定在左子树中,将root指向左子节点,继续查找  }  else if(root.val < p.val && root.val < q.val){  // 如果当前根节点的值小于p和q的值  root = root.right;  // 则最低公共祖先一定在右子树中,将root指向右子节点,继续查找  }  else{  // 如果当前根节点的值介于p和q的值之间  // 这意味着p和q分别在根节点的左右两侧或者其中一个是根节点本身  return root;  // 返回当前根节点作为最低公共祖先  }  }  // 如果root为null,说明已经遍历完整个树但没有找到p和q  // 这可能是因为p和q不在树中,或者树的构建有问题  return null;  // 返回null表示没有找到最低公共祖先  }  
}

701.二叉搜索树的插入操作

701. 二叉搜索树中的插入操作

中等

给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。

注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回 任意有效的结果 。

示例 1:

输入:root = [4,2,7,1,3], val = 5
输出:[4,2,7,1,3,5]
解释:另一个满足题目要求可以通过的树是:

示例 2:

输入:root = [40,20,60,10,30,50,70], val = 25
输出:[40,20,60,10,30,50,70,null,null,25]

示例 3:

输入:root = [4,2,7,1,3,null,null,null,null,null,null], val = 5
输出:[4,2,7,1,3,5]

提示:

  • 树中的节点数将在 [0, 104]的范围内。
  • -108 <= Node.val <= 108
  • 所有值 Node.val 是 独一无二 的。
  • -108 <= val <= 108
  • 保证 val 在原始BST中不存在。

701.二叉搜索树中的插入操作

思路就是每插入一个元素,都可以把该元素放到根节点中,所以要根据插入节点的大小找到叶子节点,下一步遇到null的时候直接将元素的大小将该元素插入该叶子节点的左节点或者右节点

递归法: 

class Solution {  public TreeNode insertIntoBST(TreeNode root, int val) {  if (root == null) {  // 如果当前节点为空,说明找到了合适的位置来插入新节点  return new TreeNode(val);  }  if (root.val < val) {  // 如果当前节点的值小于要插入的值,说明新节点应该插入到右子树中  root.right = insertIntoBST(root.right, val);  } else if (root.val > val) {  // 如果当前节点的值大于要插入的值,说明新节点应该插入到左子树中  root.left = insertIntoBST(root.left, val);  }  // 返回更新后的根节点  return root;  }  
}

 迭代法:

class Solution {  public TreeNode insertIntoBST(TreeNode root, int val) {  // 如果根节点为空,则创建一个新的节点作为根节点,并返回这个新节点  if (root == null) return new TreeNode(val);  // 初始化 newRoot 为根节点,用于返回整个树的根节点  // pre 用于记录当前节点的前一个节点,即父节点  TreeNode newRoot = root;  TreeNode pre = root;  // 使用 while 循环遍历 BST,寻找插入新节点的合适位置  while (root != null) {  // 将当前节点赋值给 pre,以便后续操作  pre = root;  // 如果当前节点的值大于要插入的值,说明新节点应该插入到左子树中  if (root.val > val) {  root = root.left;  // 如果当前节点的值小于要插入的值,说明新节点应该插入到右子树中  } else if (root.val < val) {  root = root.right;  }  }  // 退出循环后,root 为 null,说明找到了插入新节点的位置  // 根据 pre 的值决定新节点是插入到左子树还是右子树  if (pre.val > val) {  // 如果 pre 的值大于要插入的值,说明新节点应该插入到 pre 的左子树中  pre.left = new TreeNode(val);  } else {  // 否则,新节点应该插入到 pre 的右子树中  pre.right = new TreeNode(val);  } return newRoot;  }  
}

450.删除二叉搜索树中的节点

450. 删除二叉搜索树中的节点

中等

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

一般来说,删除节点可分为两个步骤:

  1. 首先找到需要删除的节点;
  2. 如果找到了,删除它。

示例 1:

输入:root = [5,3,6,2,4,null,7], key = 3
输出:[5,4,6,2,null,null,7]
解释:给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。
一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。
另一个正确答案是 [5,2,6,null,4,null,7]。

示例 2:

输入: root = [5,3,6,2,4,null,7], key = 0
输出: [5,3,6,2,4,null,7]
解释: 二叉树不包含值为 0 的节点

示例 3:

输入: root = [], key = 0
输出: []

提示:

  • 节点数的范围 [0, 104].
  • -105 <= Node.val <= 105
  • 节点值唯一
  • root 是合法的二叉搜索树
  • -105 <= key <= 105

进阶: 要求算法时间复杂度为 O(h),h 为树的高度。

有以下五种情况:

  • 第一种情况:没找到删除的节点,遍历到空节点直接返回了
  • 找到删除的节点
    • 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
    • 第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
    • 第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
    • 第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。

第五种情况有点难以理解,看下面动画:

450.删除二叉搜索树中的节点

动画中的二叉搜索树中,删除元素7, 那么删除节点(元素7)的左孩子就是5,删除节点(元素7)的右子树的最左面节点是元素8。

将删除节点(元素7)的左孩子放到删除节点(元素7)的右子树的最左面节点(元素8)的左孩子上,就是把5为根节点的子树移到了8的左孩子的位置。

要删除的节点(元素7)的右孩子(元素9)为新的根节点。.

这样就完成删除元素7的逻辑,最好动手画一个图,尝试删除一个节点试试。

这里要删除7,需要找一个只比7大一点的元素,即中序遍历的话7的后一个元素,将7的左子树放在该节点左子树的位置上,这样才能保证删除之后的二叉树还是二叉搜索树

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {  public TreeNode deleteNode(TreeNode root, int key) {  // 1.如果根节点为空,直接返回null if(root == null){  return null;  }  // 如果找到了要删除的节点 if(root.val == key){  // 2.如果要删除的节点没有左右子节点,直接返回null  if(root.left == null && root.right == null){  return null;  }  // 3.如果要删除的节点只有右子节点,返回右子节点  else if(root.left == null && root.right != null){  return root.right;  }  // 4.如果要删除的节点只有左子节点,返回左子节点  else if(root.right == null && root.left != null){  return root.left;  }  // 5.如果要删除的节点既有左子节点又有右子节点  // 找到右子树中最小的节点(即最左边的节点)  else{  TreeNode cur = root.right;  while(cur.left != null){  cur = cur.left;  }  cur.left = root.left; // 将最小节点的左子树设为要删除节点的左子树  return root.right; // 返回新的节点(原要删除节点的右子树)  }  }  // 如果要删除的节点值小于根节点的值,说明要删除的节点在左子树中  if(root.val > key){  root.left = deleteNode(root.left,key); // 递归调用deleteNode方法删除左子树中的节点  }  // 如果要删除的节点值大于根节点的值,说明要删除的节点在右子树中  if(root.val < key){  root.right = deleteNode(root.right,key); // 递归调用deleteNode方法删除右子树中的节点  }  // 返回更新后的根节点  return root;  }  
}

 669.修建二叉搜索树

669. 修剪二叉搜索树

中等

给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。

所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。

示例 1:

输入:root = [1,0,2], low = 1, high = 2
输出:[1,null,2]

示例 2:

输入:root = [3,0,4,null,2,null,null,1], low = 1, high = 3
输出:[3,2,null,1]

提示:

  • 树中节点数在范围 [1, 104] 内
  • 0 <= Node.val <= 104
  • 树中每个节点的值都是 唯一 的
  • 题目数据保证输入是一棵有效的二叉搜索树
  • 0 <= low <= high <= 104
class Solution {  public TreeNode trimBST(TreeNode root, int low, int high) {  // 如果根节点为空,则直接返回null  if(root == null){  return null;  }  // 如果根节点的值小于low,说明根节点及其左子树的所有节点值都小于low  // 因此,只需要修剪右子树,并返回修剪后的右子树作为新的根节点//这里相当于直接删除了根节点和左子树  if(root.val < low){  return trimBST(root.right,low,high);  }  // 如果根节点的值大于high,说明根节点及其右子树的所有节点值都大于high  // 因此,只需要修剪左子树,并返回修剪后的左子树作为新的根节点  //这里相当于直接删除了根节点和右子树else if(root.val > high){  return trimBST(root.left,low,high);  }  // 如果根节点的值在[low, high]的范围内,则需要同时修剪左右子树  // 修剪左子树时,要保证左子树中所有节点的值都大于等于low  // 修剪右子树时,要保证右子树中所有节点的值都小于等于high  // 修剪完成后,更新根节点的左右子树,并返回根节点  else{  root.left = trimBST(root.left,low,high);  root.right = trimBST(root.right,low,high);  }  // 返回修剪后的根节点  return root;  }  
}

108.将有序数组转换为二叉搜索树

108. 将有序数组转换为二叉搜索树

简单

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。

高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。

示例 1:

输入:nums = [-10,-3,0,5,9]
输出:[0,-3,9,-10,null,5]
解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:

示例 2:

输入:nums = [1,3]
输出:[3,1]
解释:[1,null,3] 和 [3,1] 都是高度平衡二叉搜索树。

提示:

  • 1 <= nums.length <= 104
  • -104 <= nums[i] <= 104
  • nums 按 严格递增 顺序排列

这里有一个问题:如果数组长度为偶数,中间节点有两个,取哪一个?

取哪一个都可以,只不过构成了不同的平衡二叉搜索树。

例如:输入:[-10,-3,0,5,9]

如下两棵树,都是这个数组的平衡二叉搜索树:

108.将有序数组转换为二叉搜索树

如果要分割的数组长度为偶数的时候,中间元素为两个,是取左边元素 就是树1,取右边元素就是树2。

// Solution类包含将已排序数组转换为二叉搜索树的方法  
class Solution {  // 主方法,用于启动递归过程  public TreeNode sortedArrayToBST(int[] nums) {  // 调用辅助方法,传入数组和初始边界索引  return helper(nums, 0, nums.length - 1);  }  // 辅助递归方法,用于构建二叉搜索树  public TreeNode helper(int[] nums, int left, int right) {  // 如果左边界大于右边界,说明当前子数组为空,返回null  //注意这里传入的是左闭右闭的索引区间if (left > right) {  return null;  }  // 计算中间索引,总是选择中间位置左边的数字作为根节点  int mid = (left + right) / 2;  // 创建一个新的树节点,值为数组中的中间值  TreeNode root = new TreeNode(nums[mid]);  // 递归构建左子树,左子树由中间值左边的部分数组构建  root.left = helper(nums, left, mid - 1);  // 递归构建右子树,右子树由中间值右边的部分数组构建  root.right = helper(nums, mid + 1, right);  // 返回构建好的子树的根节点  return root;  }  
}  

538.把二叉搜索树转换为累加树

538. 把二叉搜索树转换为累加树

中等

给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。

提醒一下,二叉搜索树满足下列约束条件:

  • 节点的左子树仅包含键 小于 节点键的节点。
  • 节点的右子树仅包含键 大于 节点键的节点。
  • 左右子树也必须是二叉搜索树。

注意:本题和 1038: . - 力扣(LeetCode) 相同

示例 1:

输入:[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]
输出:[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]

示例 2:

输入:root = [0,null,1]
输出:[1,null,1]

示例 3:

输入:root = [1,0,2]
输出:[3,3,2]

示例 4:

输入:root = [3,2,4,1]
输出:[7,9,4,10]

提示:

  • 树中的节点数介于 0 和 104 之间。
  • 每个节点的值介于 -104 和 104 之间。
  • 树中的所有值 互不相同 。
  • 给定的树为二叉搜索树。

累加树是使得每个节点的值是原来的节点值加上所有大于它的节点值之和。 

通过右中左的访问方式,累加每个节点,然后通过sum更新

class Solution {  // 定义一个全局变量sum,用于累加节点值  int sum = 0;  // convertBST方法接受一个二叉搜索树的根节点作为参数  // 返回转换后的二叉搜索树的根节点  public TreeNode convertBST(TreeNode root) {  // 如果根节点为空,则直接返回null  if (root == null) {  return null;  }  // 先递归处理右子树  convertBST(root.right);  // 将当前节点的值累加到sum上  sum += root.val;  // 更新当前节点的值为sum,即从最大的节点到当前节点的所有节点值的总和  root.val = sum;  // 再递归处理左子树  convertBST(root.left);  // 返回转换后的根节点  return root;  }  
}  

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

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

相关文章

浅谈MySQL 索引

MySQL 索引类型 1&#xff1a;主键索引 索引列中的值必须是唯一的&#xff0c;不允许有空值。 2&#xff1a;普通索引 MySQL中基本索引类型&#xff0c;没有什么限制&#xff0c;允许在定义索引的列中插入重复值和空值。 3&#xff1a;唯一索引 索引列中的值必须是唯一的&…

App前端开发跨平台框架比较:React Native、Flutter、Xamarin等

引言 移动应用开发领域的跨平台框架正在不断演进&#xff0c;为开发者提供更多选择。在本文中&#xff0c;我们将比较几个流行的跨平台框架&#xff1a;React Native、Flutter和Xamarin等。讨论它们的优缺点、适用场景以及开发体验。 第一部分 React Native: 优缺点、适用场景…

uniapp实现单选框卡片选择器,支持微信小程序、H5等多端

采用uniapp-vue3实现的一款单选框卡片选择器&#xff0c;纯CSS实现样式和交互&#xff0c;提供丝滑的动画选中效果&#xff0c;支持不同主题配置&#xff0c;适配多端 可到插件市场下载尝试&#xff1a; https://ext.dcloud.net.cn/plugin?id16901 使用示例 示例代码 <te…

Linux操作系统项目上传Github代码仓库指南

文章目录 1 创建SSH key2.本地git的用户名和邮箱设置3.测试连接4.创建仓库5.终端项目上传 1 创建SSH key 1.登录github官网,点击个人头像,点击Settings,然后点击SSH and GPG keys,再点击New SSH key。 Title 可以随便取&#xff0c;但是 key 需要通过终端生成。 Linux终端执行…

探究java反射取值与方法取值性能对比

探究java反射取值与方法取值性能对比 由于我开发框架时&#xff0c;经常需要对象取值。常用的取值方式有&#xff1a; 反射取值方法调用取值 环境 同一台电脑&#xff1a; jdk 21.0.2 idea 2023.3.3 1. 测试代码&#xff08;常用&#xff09; 1.1 反射取值 public stat…

【Web】浅浅地聊JDBC java.sql.Driver的SPI后门

目录 SPI定义 SPI核心方法和类 最简单的SPIdemo演示 回顾JCBC基本流程 为什么JDBC要有SPI JDBC java.sql.Driver后门利用与验证 SPI定义 SPI&#xff1a; Service Provider Interface 官方定义&#xff1a; 直译过来是服务提供者接口&#xff0c;学名为服务发现机制 它通…

如何在windows上像linux的ssh一样远程访问其它windows

主要分成两部分&#xff1a; 1. 如何远程执行指令 使用psexec&#xff0c;示例如下&#xff1a; PsExec64.exe \\远程计算机ip -u 用户名 -p 密码 -i cmd.exe 这样你就能连接到远程计算机上执行命令了&#xff0c;效果如下 2. 如何远程拷贝文件 分成两步&#xff1a; net…

【语法基础练习】1.变量、输入输出、表达式与顺序语句

&#x1f338;博主主页&#xff1a;釉色清风&#x1f338;文章专栏&#xff1a;算法练习&#x1f338;今日语录&#xff1a;You don’t know until you try. 文章简介&#xff1a;下面的题目是AcWing网站语法基础练习篇的第一小节&#xff0c;内容基础&#xff0c;难度&#xf…

计算机组成原理-累加器实验——沐雨先生

一、实验目的 1.理解累加器的概念和作用 2.连接运算器、存储器和累加器&#xff0c;熟悉计算机的数据通路 3.掌握使用微命令执行各种操作的方法。 二、实验要求 1.做好实验预习&#xff0c;读懂实验电路图&#xff0c;熟悉实验元器件的功能特性和使用方法。在实验之前设计…

list链表的创建,排序,插入, test ok

1. 链表的建立&#xff0c;打印 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <stack> #include <iostream> #include <string.h> #include <string>using namespace std;struct node {int data;s…

Vue项目性能分析工具: vue-cli-plugin-webpack-bundle-analyzer

在优化项目的时候&#xff0c;每次打包后只知道包文件大&#xff0c;却不知道那个文件大&#xff0c;那个文件还有优化的空间&#xff0c;所以&#xff0c;推荐一款工具&#xff0c;只要在项目中安装配置一下&#xff0c;便可以一目了然的呈现出打包后资源所占的比例&#xff0…

军用技术民用开花,Shokz韶音要做下一个“AirPods”

Shokz韶音对打造消费级骨传导耳机的执念始于2007年。 在这之前&#xff0c;它已经成为亚洲最大的军用耳机生产商&#xff0c;以代工订单为主的商业模式是Shokz韶音的主营业务。虽然Shokz韶音靠代工赚得了第一桶金&#xff0c;但军用耳机的垂直细分市场容量有限&#xff0c;市场…

Python 实现冒泡排序算法

Python 实现冒泡排序算法 下面是用 Python 实现的冒泡排序算法示例代码&#xff1a; def bubble_sort(arr):n len(arr)# 遍历数组元素for i in range(n):# 每次遍历都将最大的元素移动到最后for j in range(0, n-i-1):# 如果相邻的元素逆序&#xff0c;则交换它们if arr[j] …

Kafka数据推送配置 | 如何设置账号密码验证?

背景&#xff1a;之前资产信息用网络接口进行数据推送&#xff0c;但是接口推送需要验证而且反应较慢。Kafak中间件提供了另一种可行的数据推送方式&#xff0c;它可以进行消息队列推送&#xff0c;且反应速度快。但是Kafka需部署在公网环境&#xff0c;并进行登录验证&#xf…

excel 动态列导出

excel动态列&#xff0c;只好用poi来写了&#xff0c;也并不复杂&#xff0c;一样就这个件事情抽像为几步&#xff0c;就是套路了&#xff0c;开发效率就上去了。 1 准备空模板 导出操作与excel模板的导出一样&#xff0c;可以参考excel导出标准化 2 自定义SheetWriteHandler …

网络信息安全:11个常见漏洞类型汇总

一、SQL注入漏洞 SQL注入攻击&#xff08;SQL Injection&#xff09;&#xff0c;简称注入攻击、SQL注入&#xff0c;被广泛用于非法获取网站控制权&#xff0c;是发生在应用程序的数据库层上的安全漏洞。 在设计程序&#xff0c;忽略了对输入字符串中夹带的SQL指令的检查&…

定时执行专家的主要功能和使用场景

定时执行专家是一款功能强大且实用的定时任务软件。它具有以下优点&#xff1a; 功能丰富: 支持多种定时模式、多种任务类型、丰富的触发方式、强大的日志功能等。易于使用: 操作界面简洁直观&#xff0c;易于上手。稳定可靠: 运行稳定可靠&#xff0c;可长期使用。 具体来说&…

【k8s管理--集群日志管理elk】

1、ELKF日志部署框架 使用docker部署的k8s集群所有的容器日志统一都在目录&#xff1a;/var/log/containers/1、filebeat是一个轻量级的日志手机工具&#xff0c;主要功能是收集日志2、logstash通可以收集日志&#xff0c;也可以进行数据清洗&#xff0c;但是一般不用logstash来…

WordPress 从入门到精通【设置 WordPress】

前言&#xff1a;为方便演示&#xff0c;前几张图使用 Playground 环境截取 如果你还不会部署WordPress&#xff0c;请看下面的链接并使用雨云可视化构建一个WordPress站点&#xff1a; 超简单EP面板搭建WordPress网站教程 - 风屿岛 10 (biliwind.com) 进入仪表盘 在搭建完…

分享Web.dev.cn中国开发者可以正常访问

谷歌开发者很高兴地宣布&#xff0c;web.dev 和 Chrome for Developers 现在都可以通过 .cn 域名访问&#xff0c;这将帮助中国的开发者更加容易获取我们的内容。 在 .cn 域名上&#xff0c;我们已向您提供所有镜像后的内容&#xff0c;并提供支持的语言版本。 Web.dev 中国开…