Python 求二叉树路径总和

题目来源:

LeetCode113 路径总和

给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。

说明: 叶子节点是指没有子节点的节点。

              5
             / \
            4   8
           /   / \
          11  13  4
         /  \    / \
        7    2  5   1

借这道题弄懂了二叉树的实现(Java、Python)以及深度遍历、树的递归

#_*_coding:utf-8_*_


class TreeNode(object):
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution(object):
    def pathSum(self, root, sum):
        result = []
        self.help(root, sum, [], result)
        return result

    def help(self, root, sum, path, result):
        if root is None:
            return
        
        #步骤类似先序遍历
        path.append(root.val)
        #遍历根节点
        if root.left is None and root.right is None:
            if sum == root.val:
                result.append(list(path))
        #遍历左子树
        self.help(root.left, sum - root.val, path, result)
        #遍历右子树
        self.help(root.right, sum - root.val, path, result)
        path.pop()

root = TreeNode(5)
l1 = TreeNode(4)
r1 = TreeNode(8)
root.left = l1
root.right = r1
l2 = TreeNode(11)
r2 = TreeNode(13)
r3 = TreeNode(4)
l1.left = l2
r1.left = r2
r1.right = r3
l3 = TreeNode(7)
l4 = TreeNode(2)
r4 = TreeNode(5)
r5 = TreeNode(1)
l2.left = l3
l2.right = l4
r3.left = r4
r3.right = r5

slu = Solution()

t = slu.pathSum(root,22)
print(t)

总结下写递归的思路,以这道题为例:先在根节点的左子树遍历,直到叶子节点;此时递归时root(叶子节点)为None,return后跳出这次递归,进入下一个( self.help(root.right, sum - root.val, path, result) ),结果也是None,也跳出递归,接着到了path.pop(),这个就是回溯法的回退,当前路径不合适([5,4,11,7]),最后的list中的7pop删除,root回到11;接着递归,回退到4,5,这时整个左子树都结束了,最上层的(  self.help(root.left, sum - root.val, path, result) )递归结束,转到右子树开始新的递归,依此类推下去。

如果有朋友觉得我说的不清楚,copy代码debug一下就清楚了,自己跟着程序走一遍流程比什么都好懂。

以前一直不明白在树的问题上递归时一种很好的解决方式,但是思路说的头头是道,就是上手写不出来代码,出去面试错失了多少机会。这次总算对这一知识点有了一定的了解,希望越努力越幸运。

leetcode 236 最近公共祖先问题

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出: 3
解释: 节点5和节点1的最近公共祖先是节点3。

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        // LCA 问题,查阅相关资料
        if (root == null) {
            return root;
        }
        if (root == p || root == q) {
            return root;
        }
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);
##################################
        if (left != null && right != null) {
            return root;
        } else if (left != null) {
            return left;
        } else if (right != null) {
            return right;
        }
        return null;
    }
}

整个递归流程的思路:

从根节点起:

1、这个节点是否为空

2、这个节点是否是p或者q中的一个

3、以上两种都不是的情况下按先序遍历遍历左子树、右子树

4、#############下面的步骤是遍历到叶子节点后才会执行到此(叶子节点递归执行后跳出执行)

 if (left != null && right != null) {
            return root;

返回的是根节点,root是最优公共祖先

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值