ps:路径题和左下角的值做题顺序反了!
110.平衡二叉树
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。
示例 1:
给定二叉树 [3,9,20,null,null,15,7]
分析:
- 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数。——先序
- 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数。——后序
递归三部曲:
1、返回值:返回高度,但如果左右高度已经相差1了,已经不是二叉平衡树了,可以返回-1 来标记已经不符合平衡树的规则了
2、终止条件:r==null,return 0
3、单层递归逻辑:分别求左右两边高度,作差。如果两边高度差>1,则返回-1,表示已经不是平衡二叉树了;如果高度差<=1,则返回该结点的真实高度=左右两边高度较大的那个+1
注意**
返回-1:同时具备返回正常情况int,和返回正常or非正常状态 bool的能力
int getheight(struct TreeNode*r){
if(r==NULL) return 0;
int h1=getheight(r->left);
int h2=getheight(r->right);
if(h1==-1 || h2==-1) return -1;
int h=abs(h1-h2);
if(h>1) return -1;
return fmax(h1,h2)+1;
}
bool isBalanced(struct TreeNode* root) {
int h=getheight(root);
if(h==-1) return false;
return true;
}
404.左叶子之和
计算给定二叉树的所有左叶子之和。
分析:
左叶子的明确定义:节点A的左孩子不为空,且左孩子的左右孩子都为空(说明是叶子节点),那么A节点的左孩子为左叶子节点
递归三要素:
1、返回值:root以下左叶子之和
传入值:因为需要父结点,才能判断左孩子是否为左叶子,故而传入root,查找root->left是否符合条件
2、递归终止条件:root=null,return 0;
**然而注意到,当左孩子为左叶子时,仍然应遍历右子树,右子树中也会有左叶子
3、单层递归逻辑:
当遇到左叶子节点的时候,记录数值。
然后通过递归求取左子树左叶子之和,和 右子树左叶子之和。
return 相加便是整个树的左叶子之和。
int sumOfLeftLeaves(struct TreeNode* root){
int h1;
if(root==NULL) return 0;
if(root->left!=NULL && root->left->left==NULL && root->left->right==NULL){
h1=root->left->val;
}
else {h1=sumOfLeftLeaves(root->left);}//求左子树中左叶子的和
int h2=sumOfLeftLeaves(root->right);//求右子树中左叶子之和
return h1+h2;//返回root结点往下,左叶子之和
}
222.完全二叉树的节点个数
给出一个完全二叉树,求出该树的节点个数。
示例 1:
- 输入:root = [1,2,3,4,5,6]
- 输出:6
示例 2:
- 输入:root = []
- 输出:0
示例 3:
- 输入:root = [1]
- 输出:1
1、遍历所有的节点
int countNodes(struct TreeNode* root) {
if(root==NULL) return 0;
int a=countNodes(root->left);
int b=countNodes(root->right);
return (a+b+1);
}
2、层序遍历
3、利用完全二叉树性质简化
分析:判断左右子树是不是满二叉树
——是:用2^h -1的方式算左右子树的节点个数,求和,得到父结点
——不是:继续往下走
——【在完全二叉树的前提下】满二叉树:往最左遍历和往最右遍历深度是一样的
int getheight(struct TreeNode*root,int flag){
if(root==NULL) return 0;
if(flag==1){
return getheight(root->left,1)+1;
}
else return getheight(root->right,0)+1;
}
int countNodes(struct TreeNode* root) {
if(root==NULL ) return 0;
int h=getheight(root, 1);
if(h==getheight(root, 0)){
return pow(2,h)-1;
}
return countNodes(root->left)+countNodes(root->right)+1;
}
513.找树左下角的值
给定一个二叉树,在树的最后一行找到最左边的值。
**注意:
1、在while/if中定义的内容,不能在while/if外使用——因为有可能根本没能进入while/if
2、函数要修改输入值时:
设计函数时:f(*a)
调用函数时:f(&a)
1、层序遍历
int findBottomLeftValue(struct TreeNode* root) {
struct TreeNode**queue=(struct TreeNode**)malloc(sizeof(struct TreeNode*)*50000);
int front=-1,rear=-1;
int answer;
queue[++rear]=root;
while(front!=rear){
int last=rear-front;
int j=0;
while(j<last){
struct TreeNode* pop_tree=queue[++front];
if(j==0) answer=pop_tree->val;
if(pop_tree->left!=NULL) queue[++rear]=pop_tree->left;
if(pop_tree->right!=NULL) queue[++rear]=pop_tree->right;
j++;
}
}
return answer;
}
2、递归方法
无所谓使用前中后序的哪一种,因为父结点不需要进行修改或者实现相应的操作
!!出现深度更深的结点,则把curval curheight对应修改,height是维护当前节点的高度的
void dfs(struct TreeNode*root,int height,int *curval,int*curheight){
//curval 和 curheight都是要返回的,故而写成int*的形式
if(root==NULL) return;
height++;
dfs(root->left,height,curval,curheight);
dfs(root->right,height,curval,curheight);
if(height>*curheight){
*curheight=height;
*curval=root->val;
}
}
int findBottomLeftValue(struct TreeNode* root) {
int curval,curheight=0;
dfs(root,0,&curval,&curheight);
return curval;
}