代码随想录算法训练营第十五天|leetcode110. 平衡二叉树、leetcode257.二叉树的所有路径、leeetcode404.左叶子之和、leetcode222.完全二叉树的节点个数
1 leetcode110. 平衡二叉树
题目链接:110. 平衡二叉树 - 力扣(LeetCode)
文章链接:代码随想录
视频链接:后序遍历求高度,高度判断是否平衡 | LeetCode:110.平衡二叉树_哔哩哔哩_bilibili
1.1 视频看后的思路
1.1.1完整的代码
就是不断判断,对其数据存储,其实突然发现每道题思路真的都很像,就是听了觉得很简单,选择的方式是前序遍历的方法
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isBalanced(self, root: Optional[TreeNode]) -> bool:
if self.height(root) == -1:
return False
else:
return True
def height(self,node):
if node == None:
return 0
left_height = self.height(node.left)
if left_height == -1:
return -1
right_height = self.height(node.right)
if right_height == -1:
return -1
if abs(left_height-right_height) >1:
return -1
else :
return 1+max(left_height,right_height)
1.1.2 精简的代码
这个就是把if合成一句话了,当时边写的过程就想到了
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isBalanced(self, root: Optional[TreeNode]) -> bool:
if self.height(root) == -1:
return False
else:
return True
def height(self,node):
if node == None:
return 0
left_height = self.height(node.left)
right_height = self.height(node.right)
if left_height==-1 or right_height==-1 or abs(left_height-right_height) >1:
return -1
return 1+max(left_height,right_height)
1.2 小结
- 什么是平衡二叉树?就是左右子树相差的值小于等于1,才能叫平衡,就是根据这个思路对其进行迭代,进行写的
- 其他的地方好像没有需要注意的点了
2 leetcode257.二叉树的所有路径
题目链接:257. 二叉树的所有路径 - 力扣(LeetCode)
文章链接:代码随想录
视频链接:递归中带着回溯,你感受到了没?| LeetCode:257. 二叉树的所有路径_哔哩哔哩_bilibili
思考的思路:首先这道题用前序遍历,然后想着存储遍历的值,如果遇到none的时候,就想上返回;emmmm,写到这里的时候发现可以用栈对数据进行存储,然后如果遇到none弹出,继续去遍历另一边,不过自己写的话不知道怎么写
2.1 视频后的思路
其实我觉得思路上没有问题,就是不知道如何保存值,但是看了视频讲解以后,就觉得自己好像多用一个函数之类的就吃亏了,,,。但是整体思路确实现在可以想出来了
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
result = []
path = []
if root == None:
return result
self.traversal(root,path,result)
return result
def traversal(self,node,path,result):
path.append(node.val)
if node.left==None and node.right == None:
spath = '->'.join(map(str,path))
result.append(spath)
return
if node.left:
self.traversal(node.left,path,result)
path.pop()
if node.right:
self.traversal(node.right,path,result)
path.pop()
2.2 本题小结
- 主要是递归和回溯,但是写完以后发现,就是取了一个高大上的名字,也很普通,,,
- 嗯,在这里恭喜一下自己吧,思路越来越明了,虽然代码需要模仿,但是我是越来越有思路了,不再害怕递归之类的了
3 leeetcode404.左叶子之和
题目链接:404. 左叶子之和 - 力扣(LeetCode)
文章链接:代码随想录
视频链接:二叉树的题目中,总有一些规则让你找不到北 | LeetCode:404.左叶子之和_哔哩哔哩_bilibili
思考的思路:使用前序遍历,然后就是如果遇到左子树且左子树的左子树和左子树的右子树没有值,就将这个值保存,然后数进行返回
3.1 视频后的思路
首先我之前的想法前序遍历,但是前序遍历的话存在问题就是最后的最后值存储在哪里呢?好像没地方可以存储了,所以就需要使用后序遍历,遍历过程最后将值存储起来
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
if root == None:
return 0
if root.left ==None and root.right == None:
return 0
left_value = self.sumOfLeftLeaves(root.left)
if root.left and not root.left.left and not root.left.right:
left_value = root.left.val
right_value = self.sumOfLeftLeaves(root.right)
num = left_value + right_value
return num
3.2 本题小结
- 就是后序遍历的一个方法吧,感觉做了很多,但是目前掌握的还是很一般,会不明白为什么
4 leetcode222.完全二叉树的节点个数
题目链接:222. 完全二叉树的节点个数 - 力扣(LeetCode)
文章链接:代码随想录
视频链接:要理解普通二叉树和完全二叉树的区别! | LeetCode:222.完全二叉树节点的数量_哔哩哔哩_bilibili
思路:就是计算左右节点的个数,然后再加上最上面的1即可进行
4.1 视频后的思路
4.1.1 二叉树的思路
跟之前求深度一样,只是这次将两边都进行了相加的工作
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def countNodes(self, root: Optional[TreeNode]) -> int:
return self.depth(root)
def depth(self,node):
if node ==None:
return 0
depth_left = self.depth(node.left)
depth_right = self.depth(node.right)
tree_node = 1+depth_left+depth_right
return tree_node
4.1.2 满二叉树的思路
这里面有一个位运算,其实有点没想到
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def countNodes(self, root: Optional[TreeNode]) -> int:
if root == None:
return 0
left = root.left
right = root.right
left_depth,right_depth = 0,0
while left:
left = left.left
left_depth +=1
while right:
right = right.right
right_depth +=1
if left_depth==right_depth:
return (2<<left_depth)-1
left_tree = self.countNodes(root.left)
right_tree = self.countNodes(root.right)
result = left_tree+right_tree+1
return result
4.2 本题小结
- 可以使用普通二叉树中的迭代,但是也可以使用完全二叉树增加判断
5 今日小结
- 其实这几道题主要就是对二叉树遍历方式选择的一个掌握
- 对递归法的理解更加深刻了
- 在第二问的时候接触了回溯的算法,就是需要存储的一个方式