java算法day14

java算法day14

  • 222 完全二叉树的节点个数。
  • 110 平衡二叉树
  • 257 二叉树的所有路径
  • 124 二叉树中的最大路径和

222 完成二叉树的节点个数

解法1,层序遍历,迭代解法。
就是层序遍历的模板题。

/*** 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 int countNodes(TreeNode root) {Deque<TreeNode> que = new ArrayDeque<>();if(root==null){return 0;}que.offerLast(root);int count = 0;while(!que.isEmpty()){int size = que.size();count +=size;while(size>0){TreeNode temp = que.pollFirst();if(temp.left!=null){que.offerLast(temp.left);}if(temp.right!=null){que.offerLast(temp.right);}size--;}}return count;}
}

解法二:递归解法。

首先还是不要扣细节,从大体上观察,然后才是拆分子问题求解。

大体上就是计算root的左右子树的节点个数总和相加,然后算上root就是+1。
如果是为null了,那说明下面没有了,直接return 0。所以递归出口也找到了。

class Solution {public int countNodes(TreeNode root) {if(root==null){return 0;}//返回左右子树的节点总和,然后加上本层的节点。return 1+countNodes(root.left)+countNodes(root.right);}
}

110 平衡二叉树

解法1:
还是递归思想。
粗略的来想。
递归的过程中,每一层需要做的事就是计算左右子树的最大高度的绝对值相减是否大于。然后递归检查左右子树。根据这个思想可以得到。

这题我写的时候没注意到一个问题,一定要紧扣题目问什么,这题我就忘写了与题目相关的进入下一层的逻辑。

class Solution {public boolean isBalanced(TreeNode root) {//能走到这说明到底了,那就是这个过程都是满足条件,所以为trueif(root==null){return true;}//每层要干的事if(Math.abs(maxDepth(root.left)-maxDepth(root.right))>1){return false;}//进入下一层。return isBalanced(root.left) && isBalanced(root.right);}//写一个函数来递归计算左右子树的最大高度int maxDepth(TreeNode root){if(root==null){return 0;}int leftMax = maxDepth(root.left);int rightMax = maxDepth(root.right);return 1+Math.max(leftMax,rightMax);}
}

这个解法有弊端,我这种解法属于自顶向下的,所以有很多的冗余计算,冗余的地方在于,我每次进入下一层,我就要调用一次计算左右子树最大高度,算一次最大高度,那就要往下递归。

所以这就是优化的地方。因此有了解法二


解法二:自底向下解法。

https://leetcode.cn/problems/balanced-binary-tree/solutions/746538/shu-ju-jie-gou-he-suan-fa-ping-heng-er-c-ckkm/
这篇题解是我看过最直观的图解。

思路:
1.这也是做本题得到的一个新思考,怎样才能做到自顶向上? 回答是利用后序遍历的思想。在后序遍历中,我们先处理左子树,然后右子树,最后才是处理当前节点。这样就做到了得到左右子树的全部信息后才来处理当前节点。而且还是在回溯的过程中进行。
总结:后序遍历提供了自底向上的信息流

2.代码整体思路:
使用一个辅助函数height来同时计算树的高度和检查平衡性。如果树是平衡的,height返回树的实际高度。如果不平衡,返回-1。
主函数要干的就是返回这个辅助函数的返回结果,如果辅助函数返回-1,那么,在底部就有一个位置不满足平衡二叉树的条件。平衡二叉树的判定是,每个节点都要递归的满足平衡二叉树的定义。由于是自底向上返回结果,所以,这个-1的值是可以带上来的,只要做条件判断即可。

3.辅助函数的具体细节
就按上面所说的想法实现,但是用的是后序遍历。由于平衡二叉树的判断本质还是左右子树高度查,因此在每一层还是要计算左右子树的高度查。但他不一样的点就在于,结果直接是从底层开始计算,所以只要底层返回了下面的高度,就可以避免重复的计算。

接下来直接看代码。

class Solution {public boolean isBalanced(TreeNode root) {//就是返回辅助函数的结果return height(root)>=0;}//传根节点进来public int height(TreeNode root){//递归出口,到底了,返回值就是0。没有高度if(root==null){return 0;}//后序遍历的思想,先往底部走int leftHeight = height(root.left);int rightHeight = height(root.right);//这里就是到了底层之后,归 的逻辑//之前说了,一旦有一个子树不满足平衡二叉树的定义,那么整体就不满足,所以这个结果要带上去。每一层都做这样的判断,那就能够带到顶部。//返回-1的情况有三种,左子树上有不满足的,或者右子树上有不满足的,或者到当前层才不满足的。if(leftHeight==-1 || rightHeight==-1 || Math.abs(leftHeight-rightHeight)>1){return -1;}else{//能走到这说明左右子树都满足了二叉平衡树,那么加上本层的高度,往上返回。return Math.max(leftHeight,rightHeight)+1;}}
}

从底部,得出底部的信息,归的时候带上底部的信息,可以避免重复计算。从而实现优化。


二叉树路径问题

主要分为两大类。

1.自顶向下(一般路径):

就是从某一个节点(不一定是根节点),从上到下寻找路径,到某一个节点(不一定是叶节点)结束。


自顶向下解题模板

首先想想自顶向下这个过程,可以清楚的类比为前序遍历的过程。因此理解下面模板的过程中,就当为前序遍历。


不回溯版本
class Solution {//用于收集所有路径的结果集List<List<Integer>> res = new ArrayList<>();//主函数,用来启动dfs,最后返回所有路径的结果集public List<List<Integer>> findPaths(TreeNode root) {dfs(root, new ArrayList<>());return res;}private void dfs(TreeNode root, List<Integer> path) {//递归出口。一旦走到了这里,说明走到了叶子节点下面的空节点。所以下面就不用担心path.add收集到空的问题。if (root == null) return;//所以每进到下一层,就先收集节点。     path.add(root.val);//然后判断是否是叶子节点,是的话就把路径加入结果集res。然后return,这条路就已经走完了。if (root.left == null && root.right == null) {//这里也是一个细节,这里是复制一份path,因为如果直接用那份path,在之后的状态会影响到里面的元素,所以这里是复制一份路径,加入结果集。res.add(new ArrayList<>(path));return;}//这里也是递归左右子树,因为你要分开了,两条路的后面的路径肯定是不相同的,所以后面的路径要分别新弄一个副本记录。如果用同一个path,那么就会导致path里面的元素会互相影响。dfs(root.left, new ArrayList<>(path));dfs(root.right, new ArrayList<>(path));}
}
回溯版本
class Solution {
//结果集List<List<Integer>> res = new ArrayList<>();//主函数public List<List<Integer>> findPaths(TreeNode root) {dfs(root, new ArrayList<>());return res;}private void dfs(TreeNode root, List<Integer> path) {//递归出口if (root == null) return;path.add(root.val);//检查是否为叶子节点,这里不同于非回溯的点就在于,你在判断为是叶子节点后,也不能直接停下来,而是要进行回溯。即处理完这层的结果集之后,还要把刚刚加进来的元素给删了。这才完成了该叶子节点的任务。//本质还是前序遍历。if (root.left == null && root.right == null) {//我之前还对这里有疑问,感觉这里还是浪费了空间,然而事实是存储结果是必要的操作,并不是浪费空间res.add(new ArrayList<>(path));} else {//递归遍历左右子树。现在可以看到,用的一直都是同一个path了。dfs(root.left, path);dfs(root.right, path);}//回溯//这里回溯的思考很重要//回溯并不是只删除刚加入的叶子节点,而是不管是任意节点,在完成当前节点的探索之后,需要将当前节点从路径中移除。所以上面的dfs下一层之后,回来的时候还是要走remove回溯。//确保我们回到父节点时,路径恢复到进入当前节点的状态。path.remove(path.size() - 1);  // 回溯}
}

2.自顶向下(给定和的路径):

找出所有从根节点到叶子节点的路径,使得路径上所有节点的值之和等于给定的目标和。


解题模板(给定和的路径)

和一般路径基本相同,只不过在递归下去的过程中要计算对节点值求和。


不回溯写法

不回溯的模板:
用一个例子来看模板怎么用:

     5/ \4   8/   / \11  13  4
/  \      \
7    2      1

来模拟一下。
假设目标和为22。
1.那么初始调用就是pathSum(root,22)。
2.然后开始dfs(root,22,new ArrayList<>())。
3.首先处理根节点
path=[5]
sum = 22-5=17
4.递归到左子树4
path=[5,4]
sum = 17-4=13
5.递归到11
path = [5,4,11]
sum = 13-11 = 2
6.递归到7
path = [5,4,11,7]
sum = 2-7=-5
不满足条件回溯。
7.回溯到11,然后递归到2
path=[5,4,11,2]
sum=2-2=0
满足条件,添加路径[5,4,11,2]到结果集
8.回溯到4,完成左子树遍历。
9.回溯到5,开始右子树遍历。
右边的是同理的。我就不再多说。

从总体的思想来看,是前序遍历的思想。
因为访问顺序:根节点->左子树->右子树。在遍历的过程中,我们首先处理了当前节点,然后才递归的处理左右子树。

前序遍历的特性为什么能帮助解决这个问题?

1.构建路径:前序遍历运行我们在深入子树之前先处理当前节点,这正式构建从根到叶的路径所需要的,
2.早期检查:我们可以在递归进入子树之前就更新路径和,这使得我们能够在到达叶子节点时,立即判断额能否找到了符合条件的路径
3.自然的回溯:前序遍历的特性使得回溯变得非常自然,当我们完成一个节点及其子树的遍历后,正好可以讲这个节点从路径中移除。
总的来说,前序遍历是解决这种问题最直观的方式,另外的遍历都不太合适。


现在具体来看代码的细节:
可总结出几个关键点:
1.每次递归调用时创建一个新的路径列表。(因为不回溯,所以后面的路径必然是不同的,就不能公用一个path了,否则会相互影响。)
2.讲当前节点添加到新的路径列表当中
3.不需要在递归调用后进行回溯操作

class Solution {
//用来存结果集List<List<Integer>> res = new ArrayList<>();
//主函数public List<List<Integer>> pathSum(TreeNode root, int targetSum) {dfs(root, targetSum, new ArrayList<>());return res;}private void dfs(TreeNode root, int sum, List<Integer> path) {//递归出口,说明走到底了,走到空节点了,直接返回if (root == null) {return;}//每次到递归下一层的时候都需要复制一个副本,将新的节点加入之后,传递给下一层。List<Integer> newPath = new ArrayList<>(path);//节点加入路径newPath.add(root.val);//求和减去当前节点的值sum -= root.val;//判断是否满足求和,如果满足,把这条路径加入res结果集。不满足就继续递归下一层。从这里你也可以看出,即使这个题中有节点为负值,一样能解决,因为就是会把所有路径给走完。即使sum已经小于0了。只不过只有sum=0才加入结果集。if (root.left == null && root.right == null && sum == 0) {res.add(newPath);} else {//递归左右子树,把刚刚创建好的路径传递给下一层。dfs(root.left, sum, newPath);dfs(root.right, sum, newPath);}}
}

回溯写法

与回溯写法的流程基本相同,但核心在于多了一行这样的代码:path.remove(path.size() - 1);

1.这行代码是回溯算法的核心,他使得我们在探索完一个路径后,撤销最后的选择,返回到上一个状态。

2.这行代码位置的重要性。这行代码可以看到放在了递归左右子树的后面。这就说明这行代码的逻辑是在递归的归的过程中进行的。也就是后面的已经探索完了,这行代码才执行的回溯。

class Solution {
//结果集List<List<Integer>> res = new ArrayList<>();
//主函数public List<List<Integer>> pathSum(TreeNode root, int targetSum) {dfs(root, targetSum, new ArrayList<>());return res;}
//递归private void dfs(TreeNode root, int sum, List<Integer> path) {//递归出口if (root == null) {return;}//处理当前节点path.add(root.val);sum -= root.val;//处理完后进行判断,是否要加入结果集if (root.left == null && root.right == null && sum == 0) {res.add(new ArrayList<>(path));} else {//递归左右子树dfs(root.left, sum, path);dfs(root.right, sum, path);}//回溯path.remove(path.size() - 1);  // 回溯}
}

3.非自顶向下:

就是从任意节点到任意节点的路径,不需要自顶向下。

先看模板的思路:
1.问题类型:
这种方法主要用于解决非自顶而下的二叉树路径问题.这类问题的特点是最优路径不一定从根节点开始或结束.

2.核心思想:
设计一个递归函数,在遍历树的过程中同时完成两个任务.
a.更新卷据最优解
b.为父节点提供必要的信息

2.1 路径计算的核心思想
(1)路径定义
在二叉树中,路径被定义为从一个节点到另一个节点的一系列连接的边。
重要的是,这个路径可以不需要经过根节点,可以在树的任何位置。

(2)路径的特性:
路径可以是向下的(父节点到子节点)。
路径可以在某个节点处拐弯(从一个子节点经过父节点到另一个子节点)。
路径不能重复经过同一个节点。

(3)路径计算方式:
对于每个节点,我们考虑以该节点为顶点的路径。
这个路径可能包括:
(a)只有节点自身
(b) 节点加上左子树的一条路径
© 节点加上右子树的一条路径
(d) 节点加上左子树和右子树的路径(形成一个拐点)

(4)递归中的路径计算:
在递归过程中,我们自底向上计算路径。
对于每个节点:
(a) 计算并返回以该节点为起点的最优单向路径(供父节点使用)。
(b) 计算经过该节点的最优路径(可能包括左右子树),更新全局最优解。

(5)具体计算步骤:
递归到叶子节点。
在回溯过程中,对每个节点:
(a) 获取左子树的最优路径值(left)。
(b) 获取右子树的最优路径值(right)。
© 计算经过当前节点的最优路径:node.val + left + right。
(d) 更新全局最优解(如果需要)。
(e) 返回 node.val + max(left, right) 给父节点。

(6)关键点:
1.返回给父节点的值只包括单向路径,因为路径不能分叉。
2.更新全局最优解时可以考虑经过当前节点的所有可能路径,包括可能的拐点

这个方法的精妙在于,它在每个节点都考虑了所有的路径组合,同时经过巧妙的返回值设置,确保路径的合法性(不会在上层节点形成环或重复计算)
通过这这种方式,我们可以在一次遍历中,找到整个树种的最优路径,无论这个路径位于树的哪个位置,是否经过根节点,是否在中间有拐点.

class Solution {
//res用于存储全局最优解,初始化为0或Integer.MIN_VALUE,取决于问题是否允许负值路径private int res = 0;//主方法,调用递归maxPath,返回全局最优解respublic int solve(TreeNode root) {maxPath(root);return res;}//递归方法private int maxPath(TreeNode root) {//递归出口,如果节点为空,返回0,就是没有值的意思if (root == null) {return 0;}//递归左右子树,分别计算左右子树的最优路径值int left = maxPath(root.left);int right = maxPath(root.right);// 更新全局最优解res = Math.max(res, left + right + root.val);// 返回以当前节点为起点的最优解return Math.max(left, right) + root.val;}
}

细节解答:
1.为什么老是要去算这个
res = Math.max(res, left + right + root.val);
回答: 因为是从根节点,开始往左右递归的,所以整个流程走下来,全局的最长路径都已经迭代到了,最后res存的一定是树中的最长路径

  1. 为什么返回值是这个:return Math.max(left, right) + root.val;
    回答:因为做递归的时候我们都要从宏观把握一下,我们递归到底在做什么?
    我们在更新res的时候,需要用到左子树和右子树的最大长度.所以我们的返回值是需要给当前节点提供左右子树的信息,所以这里return给上一层,就是要返回本层为及本层之下的最大长度

3.有时候老是爱考虑一个问题,我一个节点,是不是有可能向上拐弯的时候取到最大值?
回答是有的,但是这里属于是多考虑了,因为你是从上面下来的,从下面下来,那不就在上面已经算过这种情况了?

4.还要看到遍历的本质,这个递归二叉树的方式可以看出是后序遍历,后序遍历有什么好处? 自底向上,减少冗余计算,允许我们在处理一个节点之前,先获取其子节点的信息,这种遍历在解决路径问题中特别有效,使得每个节点只被访问和计算了一次.

257 二叉树的所有路径

类别为:自顶向下

所以用回溯的模板做
面试建议都用回溯,这个优化的点也可以说说。

这个题有个注意的点。如果你用字符串来记录path,那么这个回溯就并没有什么意义。因为每拼接一个新的节点进来,由于字符串是不可变对象,那么就会又创建一个新的对象。因此这个题想不创建新的对象,还能不断的拼接节点进来。那我们就会想到StringBuilder。到时候将结果加入结果集就是调用toString()方法就转为了字符串。

所以现在一旦用了StringBuilder。那么就和我们的模板没什么区别了。

class Solution {
//主函数public List<String> binaryTreePaths(TreeNode root) {List<String> result = new ArrayList<>();if (root == null) return result;dfs(root, new StringBuilder(), result);return result;}//递归private void dfs(TreeNode node, StringBuilder path, List<String> result) {//递归出口if (node == null) return;//上来先计算长度。//这个长度一举两得,既能拿来判断字符串是不是空,还能用来回溯,StringBuilder做删除操作就是setLength(len)方法。int len = path.length();//一个特判,因为题目有要求结果加->,如果字符串中没有元素,就不用加->,就才加。if (len > 0) path.append("->");//加入结果集path.append(node.val);if (node.left == null && node.right == null) {//判断是否加入结果集result.add(path.toString());} else {//如果不满足,那就继续递归左右子树dfs(node.left, path, result);dfs(node.right, path, result);}//能走到这里,说明下面的路一句走完了,该回去了。这个代码一执行,说明这一层的逻辑要删除了,就要回到上一层了。path.setLength(len);  // 回溯}
}

关于StringBuilder的使用细节:
1.用于处理可变字符序列。运行我们在不创建新对象的情况下修改字符串内容。
特性:1.与String不同,可变。2.现成不安全。3.对于频繁的字符串操作,效率更高

2.增删查改操作。
1.增:
append()在末尾增。
insert(index,num)在指定位置增
2.删:
delete(begin,end) 删除指定范围
deleteCharAt(index)删除指定索引
setLength(len),适合删除末尾元素
3.查
charAt(index)根据索引查指定的
indexOf(subStr)查字串的位置
subString()获取子字符串
4.改
setCharAt()
replace()
5.其他
reverse()
length()获取当前长度。



124 二叉树中的最大路径和

直接就是上面模板中的非自顶向下模板,用了就直接结束了.

class Solution {
//题目要求里存在负值private int maxSum = Integer.MIN_VALUE;//主函数public int maxPathSum(TreeNode root) {maxGain(root);return maxSum;}//递归private int maxGain(TreeNode node) {if (node == null) {return 0;}// 递归计算左右子节点的最大贡献值// 只有在最大贡献值大于 0 时,才会选取对应子节点//这里的想法非常重要,这里产生了思考主要是因为你考虑到了全是负数的情况,在全是负数的情况,那么你应该想到,路径有不同的情况,其中一种就是节点本身.所以对最大长度没有什么共享,那就不选它就完事了,所以返回0就是压根没把这条路径选上.int leftGain = Math.max(maxGain(node.left), 0);int rightGain = Math.max(maxGain(node.right), 0);// 节点的最大路径和取决于该节点的值与该节点的左右子节点的最大贡献值int priceNewpath = node.val + leftGain + rightGain;// 更新答案(维护一个最大值)maxSum = Math.max(maxSum, priceNewpath);// 返回节点的最大贡献值return node.val + Math.max(leftGain, rightGain);}
}

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

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

相关文章

linux的学习(三):用户权限,查找,压缩命令

简介 关于用户权限&#xff0c;查找和压缩解压缩命令的简单使用 用户管理命令 useradd useradd&#xff1a;添加新用户&#xff0c;要root权限才能使用 useradd -g 组名 用户名&#xff1a;可以添加到组 创建成功会在 /home下有用户的主目录 passwd passwd 用户名&#x…

【C语言】多进程服务器

多进程服务器 多进程服务器步骤代码 最后 多进程服务器 步骤 服务器使用父进程 fork 创建子进程来和客户端进行通信&#xff0c;父进程负责取出连接请求。并且父进程接收子进程退出信号&#xff0c;通过信号处理函数回收子进程 步骤&#xff1a; 1.首先屏蔽子进程退出信号 2.使…

【WEB前端2024】3D智体编程:乔布斯3D纪念馆-第60集-agent训练资讯APP重点推荐AI资讯内容(含视频)

【WEB前端2024】3D智体编程&#xff1a;乔布斯3D纪念馆-第60集-agent训练资讯APP重点推荐AI资讯内容&#xff08;含视频&#xff09; 使用dtns.network德塔世界&#xff08;开源的智体世界引擎&#xff09;&#xff0c;策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。d…

php反序列化--2--PHP反序列化漏洞基础知识

一、什么是反序列化&#xff1f; 反序列化是将序列化的字符串还原为PHP的值的过程。 二、如何反序列化 使用unserialize()函数来执行反序列化操作 代码1&#xff1a; $serializedStr O:8:"stdClass":1:{s:4:"data";s:6:"sample";}; $origina…

Android Service的解析

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 Android服务&#xff0c;即Service&#xff0c;是Android四大组件之一&#xff0c;是一种程序后台运行的方案&am…

新增支持GIS地图、数据模型引擎升级、增强数据分析处理能力

为了帮助企业提升数据分析处理能力&#xff0c;Smartbi重点围绕产品易用性、用户体验、操作便捷性进行了更新迭代&#xff0c;同时重磅更新了体验中心。用更加匹配项目及业务需求的Smartbi&#xff0c;帮助企业真正发挥数据的价值&#xff0c;赋能决策经营与管理。 Smartbi用户…

js中使用原型链增加方法后,遍历对象的key-value时会遍历出方法

原因&#xff1a;js使用原型链实现方法时&#xff0c;这个方法默认是可迭代的&#xff0c;所以在遍历时就会被遍历出来&#xff0c; 例&#xff1a; Array.prototype.remove function(n){return this.slice(0,n).concat(this.slice(n1,this.length));}var cc ["cccaaaa…

五:C语言-操作符

五&#xff1a;操作符 1.关系操作符&#xff1a; 在C语言中用于比较的表达式&#xff0c;称为 “关系表达式” &#xff0c;里面使用的运算符就称为 “关系运算符” &#xff0c;主要有下面六个&#xff1a; 关系运算符描述>大于运算符<小于运算符>大于等于运算符&…

wifi信号处理的CRC8、CRC32

&#x1f9d1;&#x1f3fb;个人简介&#xff1a;具有3年工作经验&#xff0c;擅长通信算法的MATLAB仿真和FPGA实现。代码事宜&#xff0c;私信博主&#xff0c;程序定制、设计指导。 &#x1f680;wifi信号处理的CRC8、CRC32 目录 &#x1f680;1.CRC概述 &#x1f680;1.C…

定时器的计数模式 定时器中断时钟配置

目录 一&#xff0c;定时器的计数模式 二&#xff0c;定时器中断时钟的配置 三&#xff0c;输入和输出原理 四&#xff0c;PWM波的小简介 一&#xff0c;定时器的计数模式 1.1 定时器的计数模式分别有三种 1.2 定时器溢出的时间&#xff08;中断&#xff0c;事件产生的时间…

QT多线程下,信号槽分别在什么线程中执行,如何控制?

可以通过connect的第五个参数进行控制信号槽执行时所在的线程 connect有几种连接方式&#xff0c;直接连接、队列连接和 自动连接 直接连接&#xff08;Qt::DirectConnection&#xff09;&#xff1a;信号槽在信号发出者所在的线程中执行 队列连接&#xff08;Qt::QueuedConn…

C#面 :请列举官方常用的中间件?

在C#领域中&#xff0c;常用的官方中间件有以下几种&#xff1a; ASP.NET Core Middleware&#xff1a;ASP.NET Core中的中间件是一种处理HTTP请求和响应的组件。它们可以在请求到达控制器之前或响应返回给客户端之前执行一些操作&#xff0c;例如身份验证、日志记录、异常处理…

python初学者知识点笔记更新

文章目录 1.main函数入口2.__init__.py 文件作用3.from .applications import server解释4.变量没有修饰&#xff0c;直接创建使用1. 内置数据类型和函数2. 类和对象3.总结 5.mod app.__module__6.集合对比区分集合类型&#xff1a;混合集合类型 7.安装包失败 1.main函数入口 …

vitest 单元测试应用与配置

vitest 应用与配置 一、简介 Vitest 旨在将自己定位为 Vite 项目的首选测试框架&#xff0c;即使对于不使用 Vite 的项目也是一个可靠的替代方案。它本身也兼容一些Jest的API用法。 二、安装vitest // npm npm install -D vitest // yarn yarn add -D vitest // pnpm pnpm …

Linux 06-01:简易shell编写

考虑一下这个与shell典型的互动&#xff1a;ls、ps 用下图的时间轴来表示事件的发生次序。其中时间从左向右。shell由标识为sh的方块代表&#xff0c;它随着时间的流逝从左向右移动。shell从用户读入字符串"ls"。shell建立一个新的进程&#xff0c;然后在那个进程中运…

vs code 启动react项目,执行npm start报错原因分析

1.执行 npm start错误信息&#xff1a;npm : 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;如果包括路径&#xff0c;请确保路径正确&#xff0c;然后再试一次。 所在位置 行:1 字符: 1 npm start ~~~ CategoryInfo …

2024年5000元投影仪推荐:五千元最值得买的三款家用激光投影推荐

五千元是很多家庭购买投影仪会选择的价位&#xff0c;这个价位的投影一般属于中高端产品&#xff0c;如果懂配置&#xff0c;知道怎么选的朋友可以选到一款性价比颇高的投影&#xff0c;但是如果不会选不懂配置可能会花冤枉钱。所以五千元价位的投影该如何选择&#xff1f;市面…

企业知识库用不起来?试一下用HelpLook同步钉钉组织架构

提升企业管理和协同效率已成为增强竞争力的关键。企业通过知识管理&#xff0c;搭建内部知识库&#xff0c;将分散的经验和知识转化为系统化流程&#xff0c;减少重复解释&#xff0c;促进业务高效运作。这为企业提供了坚实的基础。 企业知识库面临的挑战 尽管传统知识库内容丰…

Jeecgboot vue3的选择部门组件JSelectDept如何实现只查询本级以及子级的部门

jeecgboot vue3的文档&#xff1a;地址 JSelectDept组件实现了弹窗然后选择部门返回的功能&#xff0c;但部门是所有数据&#xff0c;不符合需求&#xff0c;所以在原有代码上稍微改动了一下 组件属性值如下&#xff1a; 当serverTreeDatafalse的时候&#xff0c;从后端查询…

2024年7月9日~2024年7月15日周报

目录 一、前言 二、完成情况 2.1 特征图保存方法 2.1.1 定义网络模型 2.1.2 定义保存特征图的钩子函数 2.1.3 为模型层注册钩子 2.1.4 运行模型并检查特征图 2.2 实验情况 三、下周计划 一、前言 本周的7月11日~7月14日参加了机器培训的学习讨论会&#xff0c;对很多概…