110.平衡二叉树
1. 判断是否是平衡二叉树,要去看它左右子树的高度差是否超过了1
2. 求二叉树高度使用后序遍历: 左右中
3. 当我们发现左右任何一个节点,不符合我们这个平衡二叉树的条件,再往上返回的时候就不反回节点高度;
1. 直接返回-1,告诉上一层树这个不是平衡二叉树
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def isBalanced(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
# recursion
def dfs(node):
# recursion ending condition
if(node == None):
# empty node the height is 0
return 0
# post order traversal: left right middle
leftHeight = dfs(node.left)
# check left sub tree height return value is -1 or not
if leftHeight == -1:
# left sub tree is not blanaced binary tree
return -1
rightHeight = dfs(node.right)
if rightHeight == -1:
return -1
# left and right both fit condtion of balanced binary tree, check height differencec
result = 1
if abs(rightHeight - leftHeight) > 1:
# means it's not balance
result = -1
else:
# mean's it balance; left and right sub tree max height + parent node height(+1)
result = 1+max(leftHeight,rightHeight)
return result
return False if dfs(root) == -1 else True
257. 二叉树的所有路径
1. 前序遍历:
1. 这样才能让父节点指向孩子节点
2. 有递归一定会有回溯
1. 回溯的过程就在递归函数的下面
3. 为什么会有回溯的过程?
1. 一个容器来收集路径,如何把第一次路径获取的元素弹出,并收集新路径的元素,这个过程就叫做回溯
伪代码
``` c++
// 一个传节点,第一个数组用来传单条路径的,第二个数组用来返回最后答案
void travesal(node,vector<int>&path,vector<string>&result){
// 添加遍历过的路径
// 前序遍历的 中遍历(处理过程):
// 把路径的节点添加进来
// 这题有个例外;因为这题的终止条件是在叶子节点就结束了
// 如果这个卸载终止条件下面的话,我们就把最后一个叶子节点的值就落下了
// 因为我们是到叶子节点就结束了,我们路径收集的节点在放在终止条件上面
path.push_back(node->val);
// 收集到叶子节点就结束没有必要到空节点
if (node->left==null && node->right == null){
//说明到叶子节点,说明到收集结果的时候
result.push_back(path);
return;
}
// 单层处理逻辑: 前序遍历 中左右
// 左遍历: 判断一下节点不为空再去向左遍历,避免遇到空指针
if(node->left){
traversal(node->left,push,result);
//回溯
// 把第一次遇到的路径全部回退回去,直到根节点,这样才能收集另一条路径
path.pop.back();
}
// 右: 逻辑跟左相同
if(node->right){
traversal(node->right,push,result);
path.pop.back()
}
}
可运行代码
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
# recursion
def traversal(self,node,path,result):
# middle
path.append(node.val) # save path element
# recursion end, when left and right child are none
if node.left == None and node.right == None:
# mean's reach to the leaft node; collect this path
sPath = '->'.join(map(str,path)) # convert each int type number to string by using -> connect
result.append(sPath) # save to final result set
return
# pre order traversal
# left
# make sure is not empty pointer
if node.left:
self.traversal(node.left,path,result)
# 回溯
path.pop()
if node.right:
self.traversal(node.right,path,result)
path.pop()
def binaryTreePaths(self, root):
"""
:type root: TreeNode
:rtype: List[str]
"""
# define two array, one is for collect path, other one is result set
path = []
result = []
# if the node is empty
if root == None:
return result
# call recursion
self.traversal(root,path,result)
return result
404.左叶子之和
1. 左叶子:
1. 首先要是叶子;叶子节点就是左右孩子都为空成为叶子
2. 一定是父节点的左孩子这样才是左叶子
2. 如何收集元素?
1. 遍历到父元素之后;判断左孩子是否为空,同时左孩子的左右孩子都为空
2. 那么当前遍历的节点左孩子就是要处理的数据
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def sumOfLeftLeaves(self, root):
"""
:type root: TreeNode
:rtype: int
"""
# recursion end condtion
if root == None:
return 0
# if we met leaf node is empty node
if root.left == None and root.right == None:
return 0
# post order traversal
leftNum = self.sumOfLeftLeaves(root.left) # left
# makesure current left child is not empty,also the left child is left leaf(which is last node)
if root.left != None and root.left.left == None and root.left.right == None:
# cur parent node left leaf is our sum
leftNum = root.left.val
rightNum = self.sumOfLeftLeaves(root.right) # right
# left sub tree + right sub tree sum
sum_ = leftNum + rightNum
return sum_
222.完全二叉树的节点个数
1. 除了底层节点,上面都是满的。底层节点是从左到右一字排开的(必须是连续的)
2. 遍历二叉树时其子树如果是满二叉树的话,可以直接用公式计算 2^深度次方-1
3. 根节点可以根据左右子树的数量+1就可以得到完全二叉树的节点数量
4. 如何判断子树是否是满二叉树?
1. 如果是满二叉树,左右遍历的深度是相等的
2. 如果子树不是满二叉树的情况的话,继续向下遍历
3. 计算左右两侧外部深度,如果深度相同,说明是满二叉树
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def countNodes(self, root):
"""
:type root: TreeNode
:rtype: int
"""
# end recursion condtion1
if root == None:
return 0
# determine sub tree is complete Tree Node or not
left = root.left
right = root.right
leftdepth = 1
rightdepth = 1
# check left side depth
while left:
left = left.left
leftdepth += 1
# check right side depth
while right:
right = right.right
rightdepth += 1
# if left side and right side depth are equal
if leftdepth == rightdepth:
# use formal calculate the node
return (2 ** leftdepth) - 1
# each recrusion logic
# using post order traversal
leftNum = self.countNodes(root.left)
rightNum = self.countNodes(root.right)
result = leftNum + rightNum + 1
return result