路径总和 I,II,III
我刷题的时候喜欢一次吧相似的题目都刷了,正好碰到几道二叉树相关的题目,于是把他们放在一起总结一下二叉树的相关操作。本文主要解答一下几道leetcode题目:
基本思路
二叉树的问题基本都可以通过对树遍历搜索解决。一个直观的模版如下所示。当然具体问题要具体分析,在此基础上增加其他判断条件。
def fun(root):
'''
root type: TreeNode
'''
# 处理当前节点
if something==target:
pass
# 处理左孩子
fun(root.left)
# 处理右孩子
fun(root.right)
接下来是具体的解题方法。
112. 路径总和
如题目描述,是一道简单题。要求判断二叉树中是否存在一条从根节点到叶子节点的路径,使路径总和等于给定值。
那么我们从根节点开始递归,找到每一条道叶子节点的路径,判断即可,返回True或False。根据思路模版,写出一下代码。
class Solution(object):
def hasPathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: bool
"""
# 递归终止条件
if root ==None:
return False
# 处理当前节点: 判断是否为叶子节点,判断路径和是否等于sum
if root.left==None and root.right==None:
if root.val == sum:
return True
else:
return False
else:
# 处理左孩子
left = self.hasPathSum(root.left,sum-root.val)
# 处理右孩子
right = self.hasPathSum(root.right,sum-root.val)
return right or left
112. 路径总和 II
啦啦啦,进入第二题。这题稍微难了一点,题目要求输出每条路径。思路还是原来的思路,不过实现上要稍作改动。
关于这种组合问题,我们首先考虑使用回溯法。那么我们可以使用一个辅助函数来实现递归回溯的过程。具体方法见代码和注释。
class Solution(object):
def dfs(self,node,sum,path,ans):
# 处理当前节点,
if not node.left and not node.right:
if sum==0:
ans.append(path[:])
return
# 处理左孩子
if node.left:
path.append(node.left.val)
self.dfs(node.left,sum-node.left.val,path,ans)
path.pop()
# 处理右孩子
if node.right:
path.append(node.right.val)
self.dfs(node.right,sum-node.right.val,path,ans)
path.pop()
return
def pathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: List[List[int]]
"""
path = [] #记录路径
ans = [] #记录路径集合
if root:
path.append(root.val)
self.dfs(root,sum-root.val,path,ans)
return ans
437. 路径总和 III
第三题的要求明显发生了变化,路径的起点和终点不一定是根节点和叶子结点了,仅要求从上向下。最后输出路径条数。所以在判断的时候,每一个节点都可能成为路径的起点,也可能不出现在路径中,所以计数的过程中要考虑到这两种情况。
这道题同样可以借鉴上一题的思路,用回溯法搜索路径,但是起点的选择要增加额外代码。具体实现看代码和注释。
class Solution(object):
def dfs(self,root,num):
# 递归终止条件
if root==None:
return 0
ans=0
# 判断当前节点
if root.val==num:
ans+=1
# 处理左孩子
ans+=self.dfs(root.left,num-root.val)
# 处理右孩子
ans+=self.dfs(root.right,num-root.val)
return ans
def pathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: int
"""
ans= 0
if root==None:
return 0
# 如果当前节点存在于路径中
if root.val==sum: # 如果刚好是路径终点
ans+=1
ans+=self.dfs(root.left,sum-root.val) # 向左探索路径
ans+=self.dfs(root.right,sum-root.val) # 向右探索路径
# 当前节点不在路径中,分别处理左右孩子
ans+=self.pathSum(root.left,sum)
ans+=self.pathSum(root.right,sum)
return ans
最后总结
这几题我用的都是比较暴力的方法,主要是熟悉一下二叉树的操作。祝大家刷题愉快,找工作顺利