博客
关于我
LeetCode之二叉树的所有路径(257)、路径总和(112、113、437)、二叉树的直径(543)
阅读量:325 次
发布时间:2019-03-04

本文共 5722 字,大约阅读时间需要 19 分钟。

树的路径

1、 二叉树的所有路径(257)

题目描述:

给定一个二叉树,返回所有从根节点到叶子节点的路径。

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

示例:

在这里插入图片描述

题解一:递归

# Definition for a binary tree node.# class TreeNode(object):#     def __init__(self, x):#         self.val = x#         self.left = None#         self.right = Noneclass Solution(object):    def binaryTreePaths(self, root):        """        :type root: TreeNode        :rtype: List[str]        """        def construct_paths(root, path):            if root:                path += str(root.val)                if not root.left and not root.right:  # 当前节点是叶子节点                    paths.append(path)  # 把路径加入到答案中                else:                    path += '->'  # 当前节点不是叶子节点,继续递归遍历                    construct_paths(root.left, path)                    construct_paths(root.right, path)        paths = []        construct_paths(root, '')        return paths

2、路径总和(112)—判断路径和是否等于一个数

题目描述:

给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。

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

示例:
给定如下二叉树,以及目标和 sum = 22,
在这里插入图片描述
返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。

题解一:递归
思路:

1、寻找一条以root为根的、总和等于sum的路径可以分解为寻找一条以root.left为根或者以root.right为根的、总和等于sum - root.val的路径。
2、随着递归,每经过一个路径上一个非叶子节点,要寻找的值就减去了当前节点的值;
3、当到达叶子节点时,已经构成一条完整路径,此时若要寻找的值恰好和叶子节点的值相同,说明找到了一条这样的路径。

# Definition for a binary tree node.# class TreeNode(object):#     def __init__(self, x):#         self.val = x#         self.left = None#         self.right = Noneclass Solution(object):    def hasPathSum(self, root, sum):        """        :type root: TreeNode        :type sum: int        :rtype: bool        """        if root is None:#根结点为空            return False        if not root.left and not root.right:#根结点没有左右孩子           return sum==root.val        return self.hasPathSum(root.left,sum-root.val) or self.hasPathSum(root.right,sum-root.val)

在这里插入图片描述

  • 时间复杂度: O ( N ) O(N) O(N),其中 N N N 是树的节点数。对每个节点访问一次。

  • 空间复杂度: O ( H ) O(H) O(H),其中 H H H 是树的高度。空间复杂度主要取决于递归时栈空间的开销,最坏情况下,树呈现链状,空间复杂度为 O ( N ) O(N) O(N)。平均情况下树的高度与节点数的对数正相关,空间复杂度为 O ( log ⁡ N ) O(\log N) O(logN)

题解二:广度优先搜索/迭代
思路:

\quad \quad BFS 使用,存储将要遍历的节点,以及剩余路径和。如果该节点恰好是叶子节点,并且 路径和 正好等于 sum,说明找了解。

# Definition for a binary tree node.# class TreeNode(object):#     def __init__(self, x):#         self.val = x#         self.left = None#         self.right = Noneclass Solution(object):    def hasPathSum(self, root, sum):        """        :type root: TreeNode        :type sum: int        :rtype: bool        """        if not root: return False                stack = [(root, sum - root.val)]        while stack:            cur_node, cur_sum = stack.pop()            if not cur_node.left and not cur_node.right and cur_sum == 0:                return True            if cur_node.left:                stack.append((cur_node.left, cur_sum - cur_node.left.val))            if cur_node.right:                stack.append((cur_node.right, cur_sum - cur_node.right.val))        return False     
  • 时间复杂度: O ( N ) O(N) O(N),其中 N N N 是树的节点数。对每个节点访问一次。

  • 空间复杂度: O ( N ) O(N) O(N),其中 N N N 是树的节点数。

3、路径总和II(113)—找到所有路径总和等于给定目标和的路径。

题目描述:

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

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

示例:
给定如下二叉树,以及目标和 sum = 22,

在这里插入图片描述

题解一:深度优先搜索之递归

# Definition for a binary tree node.# class TreeNode(object):#     def __init__(self, x):#         self.val = x#         self.left = None#         self.right = Noneclass Solution(object):    def pathSum(self, root, sum):        """        :type root: TreeNode        :type sum: int        :rtype: List[List[int]]        """        self.result=[]        if not root:            return []                def dfs(root,tmp,sum):            if not root:                return            #叶子节点且值等于给定值            if not root.left and not root.right and root.val==sum:                tmp+=[root.val]                self.result.append(tmp)            dfs(root.left,tmp+[root.val],sum-root.val)            dfs(root.right,tmp+[root.val],sum-root.val)                   dfs(root,[],sum)        return self.result

4、路径总和III(437)—统计路径和等于给定数的路径总量

题目描述:

【中等】

给定一个二叉树,它的每个结点都存放着一个整数值。
找出路径和等于给定数值的路径总数。

路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。

二叉树不超过1000个节点,且节点数值范围是 [-1000000,1000000] 的整数。

示例:

在这里插入图片描述

思路分析

1、注意路径不一定以 根结点开头,也不一定以 叶子节点结尾,但是必须连续。

2、

题解一:深度优先搜索之递归

5、二叉树的直径(543)

题目描述:

给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。
示例 :
给定二叉树
在这里插入图片描述
返回 3, 它的长度是路径 [4,2,1,3] 或者 [5,2,1,3]。
注意:两结点之间的路径长度是以它们之间边的数目表示。

知识点

1、路径长度
\quad \quad 如果树的结点序列 n 1 , n 2 , . . . , n k n_1,n_2,...,n_k n1,n2,...,nk有如下关系:结点 n i n_i ni n i + 1 n_i+1 ni+1的双亲(1<=i<k),则把 n 1 , n 2 , . . . , n k n_1,n_2,...,n_k n1,n2,...,nk称为一条由 n i n_i ni n k n_k nk的路径,路径上经过的边的个数称为路径长度。

2、直径长度:

\quad \quad 一棵二叉树的直径长度是任意两个结点路径长度中的最大值。

思路分析:

1、初想,二叉树的直径长度=左子树高度+右子树高度,直接求根结点的左子树高度,以及右子树高度,然后再将两者相加即可;
在这里插入图片描述
2、转而一想,如果直径长度不穿过根结点,就没办法想上面那样求了,应该考虑以任意一个结点为根的直径情况:左子树高度+右子树高度,然后再求其最大值即可。

在这里插入图片描述
3、左子树高度、右子树高度采用递归法求即可,。

# Definition for a binary tree node.# class TreeNode(object):#     def __init__(self, x):#         self.val = x#         self.left = None#         self.right = Noneclass Solution(object):    def diameterOfBinaryTree(self, root):        """        :type root: TreeNode        :rtype: int        """        self.result=0#结果初始化为0        def depth(node):            #如果为空结点,返回0            if not node: return 0            #左孩子为根的子树的高度            L=depth(node.left)            #右孩子为根的子树的高度            R=depth(node.right)            #更新结果为其最大值            self.result=max(self.result,L+R)            return max(L,R)+1        depth(root)        return self.result

复杂度分析

  • 时间复杂度: O ( N ) O(N) O(N),其中 N N N 为二叉树的节点数,即遍历一棵二叉树的时间复杂度,每个结点只被访问一次。

  • 空间复杂度: O ( H e i g h t ) O(Height) O(Height),其中 H e i g h t Height Height 为二叉树的高度。由于递归函数在递归过程中需要为每一层递归函数分配栈空间,所以这里需要额外的空间且该空间取决于递归的深度,而递归的深度显然为二叉树的高度,并且每次递归调用的函数里又只用了常数个变量,所以所需空间复杂度为 O ( H e i g h t ) O(Height) O(Height)

转载地址:http://cgrh.baihongyu.com/

你可能感兴趣的文章
如何使用4G模块通过MQTT协议传输温湿度数据到onenet
查看>>
图解:网络硬件的发展史
查看>>
map的find函数和count函数
查看>>
C++并发与多线程(一)
查看>>
C++ 并发与多线程(五)
查看>>
STM32--USART串口收发数据
查看>>
逆合成孔径雷成像(一)— 傅里叶变换基础1
查看>>
7628 EDCCA认证寄存器修改(认证自适应)
查看>>
C#四行代码写简易计算器,超详细带注释(建议新手看)
查看>>
计算机网络子网划分错题集
查看>>
java一些基本程序
查看>>
数据结构之排序
查看>>
数据结构经典十套卷之八
查看>>
修改jupyter保存文件目录
查看>>
tensorflow入门变量常量
查看>>
卷积神经网络六之CNN反向传播计算过程
查看>>
神经元与神经网络一之概述
查看>>
神经网络二之手写数字识别
查看>>
神经网络四之计算损失函数
查看>>
神经网络六之反向传播
查看>>