算法题
二叉树的直径
543. 二叉树的直径 - 力扣(LeetCode)
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:
int sum=0;
int maxLenth(TreeNode*root){
if(!root)return 0;
int l=maxLenth(root->left);//遍历左子树的深度
int r=maxLenth(root->right);//遍历右子树的深度
sum=max(sum,l+r+1);//记录当前最大的直径;
return max(l,r)+1;//返回该节点的深度
}
int diameterOfBinaryTree(TreeNode* root) {
maxLenth(root);
return sum-1;
}
};
基础知识
C++ 中的异常处理机制是怎样的?
异常是一种处理错误的方式,当一个函数发现自己没有办法处理错误的时候,抛出异常,然函数的直接或者间接的调用者来处理错误
- throw 出现异常时,程序抛出异常
- catch 通过异常处理程序捕获异常,可以有多个catch捕获
- try中的代码标识将被激活的特定异常,后边通常跟着一个或者多个catch块
#include<iostream>
using namespace std;
//抛出异常
int sum(int x,int y) {
if (x == 0) {
throw "Erro x==0";
}
else {
return x + y;
}
}
void fun() {
int x, y;
cin >> x >> y;
cout << sum(x, y) << endl;
}
//在需要关注异常的地方,捕捉异常
int main() {
try {
fun();
}
catch (const char*str) {
cout << str << endl;
}
}
什么情况下应该使用异常处理?
异常是通过抛出对象而引发的,该对象的类型决定了应该激活哪个catch的处理代码。
例如:如果异常抛出是用的 int 类型 而在外部捕获中 捕获函数是用的char类型进行的捕获那么,该错误就不会被捕获到,而代码也就此终止异常继续往外传。
异常处理的优缺点是什么?
C++异常的优点:
- 异常对象定义好了,可以清晰准确的展示出错误的各种信息,这样可以帮助更好的定位程序的bug。
- 返回错误码的传统方式有个很大的问题就是,在函数调用链中,深层的函数返回了错误,那么我们得层层返回错误,最外层才能拿到错误,而在中间一部错误则错误就可能丢失。
- 很多的第三方库都包含异常,比如boost、gtest、gmock等等常用的库,那么我们使用它们也需要使用 异常。
- 很多测试框架都使用异常,这样能更好的使用单元测试等进行白盒的测试。
- 部分函数使用异常更好处理,比如构造函数没有返回值,不方便使用错误码方式处理。
缺点:
1. 异常会导致程序的执行流乱跳,非常的混乱,这会导致我们跟 踪调试时以及分析程序时,比较困难。
2. 异常会有一些性能的开销。
3. C++没有垃圾回收机制,资源需要自己管理。有了异常非常容易导致内存泄漏、死锁等异常安全问题。