专题十_穷举vs暴搜vs深搜vs回溯vs剪枝_二叉树的深度优先搜索_算法专题详细总结

目录

搜索 vs 深度优先遍历 vs 深度优先搜索 vs 宽度优先遍历 vs 宽度优先搜索 vs 暴搜

1.深度优先遍历 vs 深度优先搜索(dfs)

2.宽度优先遍历 vs 宽度优先搜索(bfs)

2.关系图暴力枚举一遍所有的情况

3.拓展搜索问题全排列

决策树

1. 计算布尔⼆叉树的值(medium)

解析:

1.函数头

2.函数体

3.函数出口

总结:

2. 求根节点到叶节点数字之和(medium)

解析:​编辑

总结:

3. ⼆叉树剪枝(medium)

总结:

4. 验证⼆叉搜索树(medium)

解析:

策略一:中序遍历,判断这个二叉树是否有序

策略二:剪枝

总结:

5. ⼆叉搜索树中第 k ⼩的元素(medium)

解析:

总结:

6. ⼆叉树的所有路径(easy)

解析:

总结:

穷举vs暴搜vs深搜vs回溯vs剪枝

什么是回溯算法

7. 全排列(medium)

解析:

1)暴力枚举:

2)递归优化:

2.设计代码:

全局变量

dfs函数

细节问题

总结:

8. ⼦集(medium)

解析:

解法一:

1.决策树

2.设计代码

全局变量

dfs

解法二:

1.画决策树

2.设计代码

总结:


搜索 vs 深度优先遍历 vs 深度优先搜索 vs 宽度优先遍历 vs 宽度优先搜索 vs 暴搜

1.深度优先遍历 vs 深度优先搜索(dfs)

2.宽度优先遍历 vs 宽度优先搜索(bfs)

那么遍历只是形式,目的是搜索

2.关系图
暴力枚举一遍所有的情况

搜索(暴搜) dfs

3.拓展搜索问题
全排列

决策树

废话不多说,直接进入例题:
 

1. 计算布尔⼆叉树的值(medium)

题目比较长,但是还是比较好理解的,0,1,2,3分别代表false,true,|,&
然后在这这个决策树上通过运算,算出最后这颗树的结果

解析:

递归函数的调用:

主要就是分三步,当主问题与子问题相同的时候:

1.函数头

2.函数体

3.函数出口

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:bool a[2]={false,true};bool evaluateTree(TreeNode* root) {if(root->left==nullptr||root->right==nullptr) return a[root->val];bool left=evaluateTree(root->left);bool right=evaluateTree(root->right);return root->val==2?left|right:left&right;}
};

总结:

只要能分析出当前问题的相同子函数,就可以得出函数体里面的内容,通过所有相同的子函数的内容进行一步步操作就能完成当前函数的任务。

2. 求根节点到叶节点数字之和(medium)

题意还是比较好理解的,就是对从根节点开始一直到叶子节点,计算每个节点当前值不断*10最后所有叶子节点的和

解析:

这种题目计算每个叶子节点的方法一眼就是dfs,先递归到叶子节点,然后就开始相加。

以下是同一种dfs的两种思想:

1.定义全局变量ret,然后每次递归到叶子节点的时候就开始进行相加,那么我就是用一个字符串s来保存每一层的临时变量,这样可以达到回溯的效果,起始不要字符串保存,只有用presum来存储临时变量也是ok的,都能存的下最终的和,然后每次到叶子节点ret就进行相加,知道加完所有叶子节点的值就完成,返回ret

唯一需要注意的就是,在传入dfs的时候就要立刻加上当前节点的值,这样就不会漏掉当前节点的某一位,因为只要到叶子节点就要开始返回上一层了,为了防止叶子节点的值给漏掉。

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:int ret=0;int sumNumbers(TreeNode* root) {string s;dfs(root,s);return ret;}void dfs(TreeNode* root,string s){s+=to_string(root->val);if(root->left==nullptr&&root->right==nullptr){ret+=stoi(s);return;}if(root->left) dfs(root->left,s);if(root->right) dfs(root->right,s);}
};

2.就是用presum来记录临时变量,不需要字符串到整形,整形到字符串的各种转换,因为最后的结果int也能存下。

看到上面的图,就能看出,如果我存临时变量presum,那么dfs返回的就是当前节点下所有叶子节点的和,那么整个二叉树就都变成了一个子问题,就是要求头节点下所有叶子节点的和。

函数头:int dfs(root,presum);

出口:就是当到达叶子节点的时候,那么就返回当前叶子节点的presum

函数体:用ret来记录当前节点下所有左右子树中,叶子节点的和,在当前节点左子树不为空下,传入dfs(root->left,presum);在当前节点右子树不为空下,传入dfs(root->right,presum);来求出当前节点下的左右子树的所有叶子节点的和

最后返回ret

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:int sumNumbers(TreeNode* root) {return dfs(root,0);}int dfs(TreeNode* root,int presum){presum=presum*10+root->val;if(root->left==nullptr&&root->right==nullptr) return presum;int ret=0;//记录当前节点下,所有叶子节点的值if(root->left) ret+=dfs(root->left,presum);if(root->right) ret+=dfs(root->right,presum);return ret; //返回给上一层}
};

总结:

像这种带有回溯类的问题,只需要考虑清楚带上的临时变量不会再中途被改变,并且再返回上一层稳定即可。

3. ⼆叉树剪枝(medium)

本题,题意比较绕,但是就是删掉所有子树全为0的节点

解析:

因为计算机不可能知道当前节点下左右子树的所有节点是否全为0,所以就要完全遍历到叶子节点在开始判断,判断叶子节点是否为0 如果是就直接置为空,并且返回空,否则就返回当前节点,不改变。

经过上面的思考,发现要先解决完所有的左子树和右子树,然后在考虑当前的节点是否为0,且左右子树是否为空,所以就完全是一个后序遍历。

1.函数头:再前面的分析里面要返回当前节点的情况,是否为空,否则就返回当前节点。说明函数头是带有返回值的。

Node* dfs(root);

2.函数体:

由于是后序遍历,先访问所有左子树,再访问右子树。然后进行判断当前节点

root->left=dfs(root->left);

root->right=dfs(root->right);

判断:如果当前节点的左右子树都为空,并且当前节点值为0,就说明这个节点也可以被删掉

if(root->left==nullptr&&root->right==nullptr&&root->val==0) root=nullptr;

return root;//将当前节点的值,返回给上一层

3.递归出口:当前节点为空的时候就返回空

if(root==nullptr) return nulltpr;

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:TreeNode* pruneTree(TreeNode* root) {if(root==nullptr) return nullptr;root->left=pruneTree(root->left);root->right=pruneTree(root->right);if(root->left==nullptr&&root->right==nullptr&&root->val==0) root=nullptr; return root;//返回给上一层}
};

总结:

写的代码很简单,但是要想清楚每一步还是很不容易,多注意细节问题,多思考,一个题目要反复思考才能被吸收。

4. 验证⼆叉搜索树(medium)

题意很简单,只要证明该树是不是二叉搜索树

解析:

策略一:中序遍历,判断这个二叉树是否有序

用prev来记录二叉树的中序的根节点,就是当前节点左子树的最右边的一个节点

要保证该二叉树是平衡二叉树,就要一直保证prev < root->val 那么就能满足条件,一旦打破了就返回false

那么:

1.函数头:bool dfs(root)

2.函数体:

弄弄左子树:bool left=dfs(root->left);

中序判断:bool ret = false;

                  if(prev<root->val) ret=true;
                  prev = root->val;

弄弄右子树:bool right=dfs(root->right);

3.出口条件:

当节点访问到空的时候,证明没有问题,返回true

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:long prev=LONG_MIN;bool isValidBST(TreeNode* root) {if(root==nullptr) return true;bool left=isValidBST(root->left);bool ret=false;if(root->val>prev) ret=true;prev=root->val;bool right=isValidBST(root->right);return left&&right&&ret;}
};

策略二:剪枝

上面策略一是访问了所有的节点,但是如果只要满足有一个节点不满足平衡二叉树的条件,不满足升序,那么就要返回false,不在往后遍历。

那么只需要再判断左子树的时候证明他是false 或者 再判断当前值不满足升序的时候都返回false就能完成剪枝操作,不在往后执行

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:long prev=LONG_MIN;bool isValidBST(TreeNode* root) {if(root==nullptr) return true;bool left=isValidBST(root->left);if(left==false) return false;bool ret=false;if(root->val>prev) ret=true;prev=root->val;if(ret==false) return false;bool right=isValidBST(root->right);return left&&right&&ret;}
};

总结:

回溯、剪枝真的没有那么神秘,再递归里面百分之99都要用到回溯,剪枝只是再我们能完成条件之后再考虑优化,我们可以尝试以下剪枝。

5. ⼆叉搜索树中第 k ⼩的元素(medium)

题意很简单,中序遍历k次的值就是第k小的元素

解析:

设置两个全局变量,ret,count,那么当count==k的时候,说明dfs再中序遍历里面已经遇到了k次中序遍历的值,得到了第k小的值

1.函数头:

void dfs(root);

2.函数体:

中序遍历,遍历到第k次时找到第k小的值:

dfs(root->left);

++count; if(count==k) ret=root->val;

dfs(root->right);

3.出口条件:

知道root==nullptr || ret != -1 就return;只要ret被改变就可以进行剪枝 

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:int ret=-1;int _k;int count=0;int kthSmallest(TreeNode* root, int k) {_k=k;dfs(root);return ret;}void dfs(TreeNode* root){if(root==nullptr||ret!=-1) return;dfs(root->left);if(++count==_k) ret=root->val;dfs(root->right);}
};

总结:

这题真的很简单,通过上面的练习,就只需要一次中序遍历就可以得到第k小的值。

6. ⼆叉树的所有路径(easy)

题意很简单,将从根节点到叶节点的所有路径放在字符串内进行返回。

解析:

虽然这题很简单,但只是有这个简单题来突破其他的难题,我们需要考虑到很多细节问题:

回溯     ->      恢复现场 的因果关系,是因为有了回溯才出现的恢复现场,不能本末倒置了。
只要有递归,那么就绝对伴随之回溯,只要有深度优先遍历,就会存在恢复现场。

为了回溯恢复现场的时候,那么就要考虑我们的参数就不能设置为全局变量,只需要把他设置为dfs的参数,那么就不需要对全局变量进行修改或删除。再每一层的临时变量都是存储当前位置的参数,不会被后面递归影响。

再考虑路径值的时候,就只需要考虑前序遍历然后添加到字符串内即可。

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:vector<string> ret;vector<string> binaryTreePaths(TreeNode* root) {string s;dfs(root,s);return ret;}void dfs(TreeNode* root,string s){if(root==nullptr) return;s+=to_string(root->val);if(root->left==nullptr&&root->right==nullptr) ret.push_back(s);else s+="->";dfs(root->left,s);dfs(root->right,s);}
};

总结:

这里对于回溯和恢复现场真的有很强的表现,强烈建议深刻理解以下恢复现场时,把参数当作临时变量真的很方便,就不需要自己再进行操作。

穷举vs暴搜vs深搜vs回溯vs剪枝

什么是回溯算法

回溯算法是⼀种经典的递归算法,通常⽤于解决组合问题、排列问题和搜索问题等。
回溯算法的基本思想:从⼀个初始状态开始,按照⼀定的规则向前搜索,当搜索到某个状态⽆法前进时,回退到前⼀个状态,再按照其他的规则搜索。回溯算法在搜索过程中维护⼀个状态树,通过遍历状态树来实现对所有可能解的搜索。
回溯算法的核⼼思想:“试错”,即在搜索过程中不断地做出选择,如果选择正确,则继续向前搜
索;否则,回退到上⼀个状态,重新做出选择。回溯算法通常⽤于解决具有多个解,且每个解都需要搜索才能找到的问题。
回溯算法的模板

void backtrack(vector<int>& path, vector<int>& choice, ...) {// 满⾜结束条件if (/* 满⾜结束条件 */) {// 将路径添加到结果集中res.push_back(path);return;}// 遍历所有选择for (int i = 0; i < choices.size(); i++) {// 做出选择path.push_back(choices[i]);// 做出当前选择后继续搜索backtrack(path, choices);// 撤销选择path.pop_back();}
}
其中, path 表⽰当前已经做出的选择, choices 表⽰当前可以做的选择。在回溯算法中,我们需要做出选择,然后递归地调⽤回溯函数。如果满⾜结束条件,则将当前路径添加到结果集中;否则,我们需要撤销选择,回到上⼀个状态,然后继续搜索其他的选择。
回溯算法的时间复杂度通常较⾼,因为它需要遍历所有可能的解。但是,回溯算法的空间复杂度较低,因为它只需要维护⼀个状态树。在实际应⽤中,回溯算法通常需要通过剪枝等⽅法进⾏优化,以减少搜索的次数,从⽽提⾼算法的效率。

7. 全排列(medium)

题意很简单,就是枚举所有可能的排列情况,那么废话不多说就是话决策树。

解析:

1)暴力枚举:

两层三层循环还可以枚举,如果要排列100层的数,那简直不可能,只能借助递归来思考。

2)递归优化:

1.画出决策树:越详细越好

2.设计代码:

全局变量

int [][] ret

int [] path

bool [] check 实现剪枝

dfs函数

就需要关系某一个节点在干什么事情

细节问题

回溯:

1.干掉path最后一个元素

2.修改check数组

剪枝

递归出口:遇到叶子节点就直接添加结果

class Solution {
public:vector<vector<int>> ret;vector<int> path;bool check[7];vector<vector<int>> permute(vector<int>& nums) {dfs(nums);return ret;}void dfs(vector<int>& nums){if(path.size()==nums.size()){ret.push_back(path);return;}for(int i=0;i<nums.size();i++){if(check[i]==false){path.push_back(nums[i]);check[i]=true;dfs(nums);path.pop_back();check[i]=false;}}}
};

总结:

最重要的就是画出决策树,越细致越好,然后通过决策树来观察代码该如何书写。

8. ⼦集(medium)

题意很简单,就是返回数组nums的所有子集。

解析:

解法一:

1.决策树

2.设计代码

全局变量

vector<vector<int>> ret; //来记录整体传入的子集
    vector<int> path;  //设置全局变量,来保证传参,然后进行手动删除

dfs

细节问题:剪枝,回溯,递归出口

传入nums后,要考虑当前位置是否选择,分为选择和不选择两种

如果选择,那么就是ret.push_back(path+nums[i])

不选择就是ret.push_back(path)

但是这里要注意的就是不选择要在选择前面,这样方便后面选择后的手动删除。再就是dfs传入后就是传入到下一层,i+1,表示的就是下一层的层数,此时回溯到这一层i也不会被改变。

递归出口:就是在i的层数在nums.size()的时候就进行最后的添加,然后进行返回。

class Solution {
public:vector<vector<int>> ret;vector<int> path;int check[10];vector<vector<int>> subsets(vector<int>& nums) {dfs(nums,0);return ret;}void dfs(vector<int>& nums,int i){if(nums.size()==i){ret.push_back(path);return;}//不选dfs(nums,i+1);path.push_back(nums[i]);//选dfs(nums,i+1);path.pop_back();}
};

解法二:

1.画决策树

2.设计代码

全局变量

vector<vector<int>> ret; //来记录整体传入的子集
    vector<int> path;  //设置全局变量,来保证传参,然后进行手动删除

dfs

细节问题:回溯 剪枝 递归出口 

只用关心每层进去后当前nums下标值的后面的值,前面的值不用考虑

例如:在1中选2,1中选3不选2,就是在for循环内进行的,当进入下一层选2,回来这个数组就会删掉2,i++,再次进入下一层选3.

class Solution {
public:vector<vector<int>> ret;vector<int> path;vector<vector<int>> subsets(vector<int>& nums) {dfs(nums,0);return ret;}void dfs(vector<int>& nums,int k){ret.push_back(path);for(int i=k;i<nums.size();i++){path.push_back(nums[i]);dfs(nums,i+1);path.pop_back();}}
};

总结:

我觉得最关键的就是画出决策图然后再进行思考递归出口或者函数体里面的内容,像这一题就是跟上一题决策树完全不同,思考的方向就完全不同。

总结一下吧~这章对我的进步真的很大,希望对你也是!!!

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

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

相关文章

JAVA智能国际商城跨境电商系统小程序源码

智能国际商城跨境电商系统——全球购物&#xff0c;一触即达 &#x1f30d; 开篇&#xff1a;智能科技&#xff0c;重塑跨境购物新体验 在这个全球化的时代&#xff0c;跨境购物已经不再是遥不可及的事情。而“智能国际商城跨境电商系统”正是这样一款将智能科技与跨境电商完…

Badge插件的用法

文章目录 1 概念介绍2 实现方法3 示例代码我们在上一章回中介绍了WebView组件相关的内容,本章回中将介绍如何在图标旁边添加小红点.闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 在实际项目中有时候需要在图标旁边显示小红点,而且小红点内还有数字,比如购物车图标显示…

柯桥外语培训韩语学习考级韩语中TOPIK常用语法表达

-기 위해서는 -는 것이 좋다 为了......&#xff0c;......比较好 -는 것보다는 -는 것이 좋다 比起......&#xff0c;......比较好 -(으)려면 -아/어/야 한다 如果想......的话&#xff0c;得...... -왜냐하면 -기 때문이다 因为...... -그 이유는 -기 때문이다 理由是…

【JAVA面试题】Java和C++主要区别有哪些?各有哪些优缺点?

文章目录 强烈推荐前言区别&#xff1a;1. 语法和编程风格2.内存管理3.平台独立性4.性能5.指针和引用6.多线程7.使用场景 Java 的优缺点优点&#xff1a;缺点&#xff1a; C 的优缺点优点&#xff1a;缺点&#xff1a; 总结专栏集锦 强烈推荐 前些天发现了一个巨牛的人工智能学…

【第三版 系统集成项目管理工程师】第15章 组织保障

持续更新。。。。。。。。。。。。。。。 【第三版】第十五章 组织保障 15.1信息和文档管理15.1.1 信息和文档1.信息系统信息-P5462.信息系统文档-P546 15.1.2 信息(文档)管理规则和方法1.信息(文档)编制规范-P5472.信息(文档)定级保护-P5483.信息(文档)配置管理-P549练习 15.…

DP35 【模板】二维前缀和

文章目录 1.题目描述输入描述&#xff1a;输出描述&#xff1a; 示例1 2.思路3.代码 1.题目 DP35 【模板】二维前缀和 描述 给你一个 n 行 m 列的矩阵 A &#xff0c;下标从1开始。 接下来有 q 次查询&#xff0c;每次查询输入 4 个参数 x1 , y1 , x2 , y2 请输出以 (x1, …

大文件-分片下载

0.需求背景 文件过大&#xff0c;单次文件流数据过多需要有下载进度需要提高下载速度 1.大文件下载的解决思路 获取文件大小&#xff0c;根据实际网络情况设置分片大小&#xff0c;确定份数根据分片的大小索引&#xff0c;获取分片的流数据所有的分片下载后&#xff0c;合并…

计算机毕业设计 基于Flask+vue的博客系统的设计与实现 Python毕业设计 Python毕业设计选题 Flask框架 Vue【附源码+安装调试】

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

Python绘制--绘制心形曲线

今天&#xff0c;我们将通过Python代码来绘制一个心形曲线&#xff0c;这是一个经典的数学表达。 一、心形曲线的数学原理 心形曲线&#xff0c;也被称为心脏曲线&#xff0c;是一个代数曲线&#xff0c;可以通过参数方程定义。其数学表达式如下&#xff1a; x16sin⁡3(t)x16…

1,STM32CubeMX生成第一个freeRTOS工程

1&#xff0c;前言 本章内容是CubeMX工程配置freeRTOS的demo工程&#xff0c;后续其他本专栏文章中不再提及&#xff0c;默认在本章内容上完成。 单片机型号&#xff1a;STM32F407 编程环境 &#xff1a;STM32CubeMX Keil v5 2&#xff0c;STM32CubeMX新建工程 双击打开ST…

新增数据集 SDK、“关系抽取”文本标注、优化模型监控和管理|ModelWhale 版本更新

ModelWhale 带来了新一轮的版本更新&#xff0c;期待为大家带来更优质的使用体验。 本次更新中&#xff0c;ModelWhale 主要进行了以下功能迭代&#xff1a; 数据管理&#xff1a;新增 mw_python_sdk 支持通过查看、下载、制作、更新数据集 文本标注&#xff1a;新增“关系抽取…

最新版本SkyWalking【10.1.0】部署

这里写目录标题 前言前置条件启动Skywalking下载解压启动说明 集成Skywalking Agent下载Agent在IDEA中添加agent启动应用并访问SpringBoot接口 说明 前言 基于当前最新版10.1.0搭建skywalking 前置条件 装有JDK11版本的环境了解SpringBoot相关知识 启动Skywalking 下载 地…

停车位识别数据集 图片数量12416张YOLO,xml和txt标签都有; 2类类别:space-empty,space-occupied;

YOLO停车位识别 图片数量12416张&#xff0c;xml和txt标签都有&#xff1b; 2类类别&#xff1a;space-empty&#xff0c;space-occupied&#xff1b; 用于yolo&#xff0c;Python&#xff0c;目标检测&#xff0c;机器学习&#xff0c;人工智能&#xff0c;深度学习&#xff0…

WordPress修改固定链接后301的重定向方法

网站改版实际上是很忌讳的&#xff0c;尤其是针对已被搜索引擎收录的网站&#xff0c;新站不用考虑这些问题&#xff0c;而已经收录的网站网页在不遵守搜索引擎规则的前提下&#xff0c;是会被降权&#xff0c;关键词排名下滑、流量IP会被剥夺、收录会减少 、业务成交量会急剧下…

Java—逻辑控制与输入输出

各位看官&#xff1a;如果您觉得这篇文章对您有帮助的话 欢迎您分享给更多人哦 感谢大家的点赞收藏评论&#xff0c;感谢您的支持&#xff01;&#xff01;&#xff01; 一.顺序结构&#xff1a; 我每天起床&#xff0c;躺在床上玩手机&#xff0c;然后吃中午饭&#xff0c;睡…

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(2)Keras

文章目录 前言一、Keras二、使用Kears 估计回归问题的神经网络1. 载入、处理数据2. 数据预处理&#xff1a;归一化3. 设定一系列随机数种子4. 定义了一个简单的深度神经网络5. 训练模型6. 查看训练结果7. 使用最优轮数&#xff08;index1&#xff09;重新估计 此神经网络模型8.…

Authentication Lab | Timing Attacks

关注这个靶场的其它相关笔记&#xff1a;Authentication Lab —— 靶场笔记合集-CSDN博客 0x01&#xff1a;Timing Attacks 前情提要 由于软件系统对不同输入处理时间的差异&#xff0c;可能会导致系统存在侧信道攻击的隐患。比如&#xff0c;如果输入的是无效的用户名&#x…

通信工程学习:什么是三网融合

三网融合 三网融合&#xff0c;又称“三网合一”&#xff0c;是指电信网、广播电视网、互联网在高层业务应用上的深度融合。这一概念在近年来随着信息技术的快速发展而逐渐受到重视&#xff0c;并成为推动信息化社会建设的重要力量。以下是对三网融合的详细解释&#xff1a; 一…

LeetCode题练习与总结:生命游戏--289

一、题目描述 根据 百度百科 &#xff0c; 生命游戏 &#xff0c;简称为 生命 &#xff0c;是英国数学家约翰何顿康威在 1970 年发明的细胞自动机。 给定一个包含 m n 个格子的面板&#xff0c;每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态&#xff1a; 1 即…

HTML图形

HTML图形 1. HTML5 Canvas2.HTML5 内联 SVG3.HTML 5 Canvas vs. SVG 1. HTML5 Canvas HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像。画布是一个矩形区域&#xff0c;您可以控制其每一像素。canvas 拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。 1、创建…