今天继续dfs简单题,二叉树的两个题目:
111 二叉树的最小深度
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7]
,
3 / \ 9 20 / \ 15 7
返回它的最小深度 2.
思路:
很简单,递归下去从叶节点开始往回返回各节点高度,取左右子树中高度较小的一个+1即可。一个坑点在于,树只靠一边偏侧的时候(即比如全是右子节点构成的树),一些点左子树高度为0,但是不能以0来加,应该完全取另一侧的树高度+1。于是代码如下:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def minDepth(self, root):
"""
:type root: TreeNode
:rtype: int
"""
if not root:
return 0
else:
return self.findHeight(root)
def findHeight(self, node):
if (not node.left) and (not node.right):
return 1
else:
if (not node.left) and node.right:
return self.findHeight(node.right) + 1
elif (not node.right) and node.left:
return self.findHeight(node.left) + 1
else:
leftval = self.findHeight(node.left)
rightval = self.findHeight(node.right)
return min(leftval, rightval) + 1
Leetcode上通过了,beat只有6%。想到,比如在判断完左子树后,发现最小高度是2,去找右子树的最小高度,但是右子树比较深,找了太久,所以应该在找完左子树后,带入一个当前最小值,超过最小值就不用向下再找了。有了这个思路但是没有写,自己记得就好。
101 对称二叉树
给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [1,2,2,3,4,4,3]
是对称的。
1 / \ 2 2 / \ / \ 3 4 4 3
但是下面这个 [1,2,2,null,3,null,3]
则不是镜像对称的:
1 / \ 2 2 \ \ 3 3
说实话一开始理解错题意了。
两个点。第一,一开始写的,是判断任意子树是否对称,但显然不是,题目的要求是从整体角度看(从根节点看)整个树是不是对称。
第二,我用的中序遍历记录结果的方法:先中序遍历,然后对遍历结果进行头尾两指针向中间查找判断的方法。可以说LeetCode用例这方面做得是真NB,第一次错在一个用例【1,2,2,null,3,null,3】,中序遍历结果是对称的,但是null没体现出来,所以结果不对。我对null加判断,如果是null添上一个Float(‘inf’)表示空值;结果下一个用例【5,4,1,null,1,null,4,2,null,2,null】简直设计到天上去了,尼玛带null之后中序遍历的结果还是对称的!但其实树型不对称……我改用随机数random对null的格填充,结果弹出来说不让用外部模块……去你妹的……
所以看了disscussion里大神的做法。简单的一个思路是:每次直接判断某节点的左右子树是否对称:如果左右子都是空,证明这个节点是个纯粹的叶节点,返回TRUE;如果有单子树(一边有一边没有),就返回False;如果左右子树都不空,先比较val值,不等的返回False;值也相等的,返回(左的左和右的右)and(左的右和右的左)的布尔值。
这相当于自顶向下的先从结构再从值的角度判断对称,代码也非常简洁,我自己写了一版:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def isSymmetric(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
if not root:
return True
else:
return self.helper(root.left, root.right)
def helper(self, tl, tr):
if (not tl) and (not tr):
return True
elif not tl or not tr:
return False
else:
if tl.val != tr.val:
return False
else:
return (self.helper(tl.left, tr.right) and self.helper(tl.right, tr.left))
修改的新代码一次通过,beat84%。也是又补充了二叉树检索部分的经验。明天争取继续!