102. 二叉树的层序遍历
vector<vector<int>> levelOrder(TreeNode* root) {
if(!root) return {};
vector<int> tmp;
vector<vector<int>> ans;
queue<TreeNode*> que;
que.push(root);
while( !que.empty() ){
int size = que.size();
tmp.clear(); //注意这里 之前没清空
for( int i = 0; i<size; ++i){
TreeNode* node = que.front();
que.pop();
tmp.push_back(node->val);
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
ans.push_back(tmp);
}
return ans;
}
101. 对称二叉树
给你一个二叉树的根节点 root
, 检查它是否轴对称。
【分析】:转化成判断两颗树:左子树和右子树
bool TreeCompare(TreeNode* leftRoot, TreeNode* rightRoot)
{
if(!leftRoot && !rightRoot) return true; //到叶子返回
//两棵树不对称,一个为空
if((leftRoot && !rightRoot) || (!leftRoot && rightRoot) ) return false;
//比较当前结点 左右节点
if(leftRoot->val != rightRoot->val) return false;
bool leftRes = TreeCompare(leftRoot->left, rightRoot->right);
bool rightRes = TreeCompare(leftRoot->right, rightRoot->left);
return leftRes && rightRes;
}
bool isSymmetric(TreeNode* root) {
//比较两棵树:左右子树
return TreeCompare(root->left, root->right);
}
104. 二叉树的最大深度
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
【分析】递归遍历,返回左右子树深度最大+1 开始想遍历到叶子节点,if中判断叶子节点 但是左右递归的时候没有判断导致传入了空指针。
int getDepth(TreeNode* node){
if(!node) return 0;
int leftDepth = getDepth(node->left);
int rightDepth = getDepth(node->right);
return leftDepth > rightDepth? leftDepth+1 : rightDepth+1;
}
2.层序遍历
int maxDepth(TreeNode* root) {
if(!root) return 0;
//层序遍历 记录层数
int depth = 0;
queue<TreeNode*> que;
que.push(root);
TreeNode* node = nullptr;
while( !que.empty() ){
depth++; //每层循环深度+1
int size = que.size();
//处理当前层的节点
for(int i = 0; i<size; ++i){
node = que.front();
que.pop();
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
}
return depth;
}
111. 二叉树的最小深度
【分析】
1.递归迭代
和最大深度的差别:最大深度直接返回左右最大的哪个
最小深度可能会出现x结点没有左子树,但是有右子树,x并不是叶子节点,不能返回深度更小的左
需要判断处理两种特殊情况,除此之外才能直接比较大小返回小+1
int getMinDepth(TreeNode* node){
//找到叶子节点 返回1
if(!node) return 0;
//比较当前左右子树 返回最小+1
int depth = 0;
int leftDepth = 0, rightDepth = 0;
leftDepth = getMinDepth(node->left);
rightDepth = getMinDepth(node->right);
// 当一个左子树为空,右不为空,这时并不是最低点
if (node->left == NULL && node->right != NULL) {
return 1 + rightDepth;
}
// 当一个右子树为空,左不为空,这时并不是最低点
if (node->left != NULL && node->right == NULL) {
return 1 + leftDepth;
}
depth = min(leftDepth, rightDepth)+1;
return depth;
}
2.层序
还是一样的层序遍历,在每层的处理中 判断当前结点是否是叶子结点,找到的第一个叶子就是深度最小的。直接break返回
int getMinDepth(TreeNode* node){
int depth = 0;
queue<TreeNode*> que;
que.push(node);
while( !que.empty() ){
int size = que.size();
depth++;
for(int i = 0; i<size; ++i){
node = que.front();
que.pop();
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
if( !node->left && !node->right) //判断是否为叶子结点
return depth;
}
}
return depth;
}
【分析】
最简单的直接遍历,尝试利用完全二叉树的性质
满二叉树是特殊的完全二叉树,可以在完全二叉树中找满二叉树,利用公式计算满二叉树的节点个数
满二叉树的判断:左深度 == 右深度
1.空 返回
2.左侧深度 右侧深度 如果相等,返回2^n -1;
3.返回 左+右+1;
int getCount(TreeNode* root){
if(root == nullptr) return 0;
int leftDepth = 0, rightDepth = 0;
TreeNode* pleft = root->left;
TreeNode* pright = root->right;
while(pleft){ //左子树深度
pleft = pleft->left;
leftDepth++;
}
while(pright){ //右子树深度
pright = pright->right;
rightDepth++;
}
//如果是满二叉树 可以直接计算返回
if(rightDepth == leftDepth){
//如果到叶子节点 2<<0-1 = 1
return (2 << leftDepth) - 1;
}
//不是满二叉树 要计算左右子树
return getCount(root->left) + getCount(root->right) +1;
}
int countNodes(TreeNode* root) {
return getCount(root);
}
【注意】 2^n的计算 n>0,实际就是2左移n-1位 2<<(n-1)
110. 平衡二叉树
int Balanced(TreeNode* node){
if(node == nullptr) return 0;
//计算在左右高度
int ldepth = Balanced(node->left);
int rdepth = Balanced(node->right);
//差绝对值<1 是
if( (ldepth == -1 )|| (rdepth == -1) ) return -1;
if( abs(ldepth-rdepth) <= 1 ){
return max(ldepth, rdepth)+1;
}
return -1;
}
bool isBalanced(TreeNode* root) {
if(Balanced(root) == -1) return false;
return true;
}