路径总和 I,II,III

路径总和 I,II,III

我刷题的时候喜欢一次吧相似的题目都刷了,正好碰到几道二叉树相关的题目,于是把他们放在一起总结一下二叉树的相关操作。本文主要解答一下几道leetcode题目:

112. 路径总和

112. 路径总和 II

437. 路径总和 III

基本思路

二叉树的问题基本都可以通过对树遍历搜索解决。一个直观的模版如下所示。当然具体问题要具体分析,在此基础上增加其他判断条件。

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

最后总结

这几题我用的都是比较暴力的方法,主要是熟悉一下二叉树的操作。祝大家刷题愉快,找工作顺利

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值