Python世界:力扣题110,平衡二叉树判别,easy
- 任务背景
- 思路分析
- 代码实现
- 测试套件
- 本文小结
任务背景
问题来自力扣题目:110 Balanced Binary Tree,大意如下:
Given a binary tree, determine if it is height-balanced。
翻译下,需求是:判断给定二叉数是否高度平衡。
思路分析
想练手下二叉树的遍历,结果在easy级上踩了坑,容我细细道来。注意本题中前置条件已默认是二叉树输入,不用考虑非二叉的输入场景。
于是,我把题意理解为,求该树中最小遍历深度和最大遍历深度,两者之差不应超过1.
# Definition for a binary tree node.
class TreeNode(object):def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightdepth = 0
depth_min = 2**31
depth_max = -1
class Solution(object):def isBalanced(self, root):""":type root: Optional[TreeNode]:rtype: bool"""flag_res = Trueif root == None:return flag_resdef recursive(node):global depth, depth_max, depth_minif node == None:depth_max = max(depth_max, depth)depth_min = min(depth_min, depth)returnprint(node.val)depth = depth + 1recursive(node.left)recursive(node.right)depth = depth - 1# 重要:每次需重新初始化全局变量,否则深度最值不准global depth, depth_max, depth_mindepth_min = 2**31depth_max = -1recursive(root)if (depth_max - depth_min > 1):print(depth_max, depth_min)flag_res = Falsereturn flag_res
初步用例通过后,提交发现这个用例错误:
# case true 错误理解,失败用例
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
root.left.left.left = TreeNode(8)
root.right.right = TreeNode(3)
root.right.left = TreeNode(6)
才幡然醒悟,题意理解偏了,二叉树是否平衡,本质问的是:平衡树指每个节点的左右两个子树深度差异最大不超过2。
所以,我们应该求:对每个左右子树求取最大深度,比较左右子树差异。
代码实现
# Definition for a binary tree node.
class TreeNode(object):def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightclass Solution(object):def isBalanced(self, root):""":type root: Optional[TreeNode]:rtype: bool"""# get the max depth of treedef recursive(node):if node == None:return 0depth_left = recursive(node.left)depth_right = recursive(node.right)if depth_left < 0 or depth_right < 0:return -1 # 已有子树不平衡if abs(depth_left - depth_right) > 1:return -1 # 当前不平衡return max(depth_left, depth_right) + 1 # 左右子树深度上提depth = recursive(root)return (depth >= 0) # 非负则平衡,负则不平衡
测试套件
单例测试版主调:
# case true
root = TreeNode(1)# case true
root = None# case true
root = TreeNode(0)
root.left = TreeNode(1)
root.right = TreeNode(2)# case false
root = TreeNode(1)
root.right = TreeNode(2)
root.right.left = TreeNode(3)# case true
root = TreeNode(0)
root.left = TreeNode(1)
root.right = TreeNode(2)
root.right.right = TreeNode(3)# case true 错误理解,失败用例
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
root.left.left.left = TreeNode(8)
root.right.right = TreeNode(3)
root.right.left = TreeNode(6)sol = Solution()
res = sol.isBalanced(root)
print(res)
测试套版主调:
import unittestdef test_base(self, root, ret):sol = Solution()res = sol.isBalanced(root)self.assertEqual(res, ret)# 编写测试套
class TestSol(unittest.TestCase):def test_special1(self):ret = Trueroot = TreeNode(1)test_base(self, root, ret)def test_special2(self):ret = Trueroot = Nonetest_base(self, root, ret)def test_common1(self):ret = Trueroot = TreeNode(0)root.left = TreeNode(1)root.right = TreeNode(2)test_base(self, root, ret)def test_common2(self):ret = Falseroot = TreeNode(1)root.right = TreeNode(2)root.right.left = TreeNode(3)test_base(self, root, ret)def test_common3(self):ret = Trueroot = TreeNode(0)root.left = TreeNode(1)root.right = TreeNode(2)root.right.right = TreeNode(3)test_base(self, root, ret)def test_common4(self):ret = True # 错误理解,失败用例root = TreeNode(1)root.left = TreeNode(2)root.right = TreeNode(3)root.left.left = TreeNode(4)root.left.right = TreeNode(5)root.left.left.left = TreeNode(8)root.right.right = TreeNode(3)root.right.left = TreeNode(6)# 测试套版本主调
if __name__ == '__main__':print('start!')unittest.main() # 启动单元测试print('done!')
本文小结
呜乎,通过本文实践,简单的事情切不可大意,再次感受到:做正确的事,比正确的做事更重要!
相关参考:https://leetcode.com/problems/balanced-binary-tree/solutions/2428871/very-easy-100-fully-explained-c-java-python-javascript-python3/