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 = val
self.left = left
self.right = right
depth = 0
depth_min = 2**31
depth_max = -1
class Solution(object):
def isBalanced(self, root):
"""
:type root: Optional[TreeNode]
:rtype: bool
"""
flag_res = True
if root == None:
return flag_res
def recursive(node):
global depth, depth_max, depth_min
if node == None:
depth_max = max(depth_max, depth)
depth_min = min(depth_min, depth)
return
print(node.val)
depth = depth + 1
recursive(node.left)
recursive(node.right)
depth = depth - 1
# 重要:每次需重新初始化全局变量,否则深度最值不准
global depth, depth_max, depth_min
depth_min = 2**31
depth_max = -1
recursive(root)
if (depth_max - depth_min > 1):
print(depth_max, depth_min)
flag_res = False
return 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 = val
self.left = left
self.right = right
class Solution(object):
def isBalanced(self, root):
"""
:type root: Optional[TreeNode]
:rtype: bool
"""
# get the max depth of tree
def recursive(node):
if node == None:
return 0
depth_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 unittest
def test_base(self, root, ret):
sol = Solution()
res = sol.isBalanced(root)
self.assertEqual(res, ret)
# 编写测试套
class TestSol(unittest.TestCase):
def test_special1(self):
ret = True
root = TreeNode(1)
test_base(self, root, ret)
def test_special2(self):
ret = True
root = None
test_base(self, root, ret)
def test_common1(self):
ret = True
root = TreeNode(0)
root.left = TreeNode(1)
root.right = TreeNode(2)
test_base(self, root, ret)
def test_common2(self):
ret = False
root = TreeNode(1)
root.right = TreeNode(2)
root.right.left = TreeNode(3)
test_base(self, root, ret)
def test_common3(self):
ret = True
root = 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/