解题思路:
1、采用深度优先搜索的方式,枚举每一条从根节点到叶子节点的路径。当我们遍历到叶子节点,且此时路径和恰为目标和时,我们就找到了一条满足条件的路径。
2、我们也可以采用广度优先搜索的方式,遍历这棵树。当我们遍历到叶子节点,且此时路径和恰为目标和时,我们就找到了一条满足条件的路径。为了节省空间,我们使用哈希表记录树中的每一个节点的父节点。每次找到一个满足条件的节点,我们就从该节点出发不断向父节点迭代,即可还原出从根节点到当前节点的路径。
举例说明:
采用深度优先搜索的方式:
二叉树:{10,5,12,4,7}, 目标值:22
根据二叉树可以枚举出所有从根节点到叶子节点的路径【10,5,4】、【10,5,7】、【10,12】
将不同的路径节点值相加,并判断符合结果等于目标值的路径:【10,5,7】、【10,12】
图表题解:
步骤 | 二叉树序列 | 目标值 | 路径列表 | 返回路径集合 |
1 | {10,5,12,4,7} | 22 | 【10】 | |
2 | 根左子树{5,4,7} | 12 | 【10,5】 | |
3 | 左子树{4} | 7 | 【10,5,4】 | |
4 | 右子树{7} | 7 | 【10,5,7】 | 【【10,5,7】】 |
5 | 根右子树{12} | 12 | 【10,12】 | 【【10,5,7】,【10,12】】 |
代码:
Python版本:
# -*- coding:utf-8 -*- # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution: # 返回二维列表,内部每个列表表示找到的路径 def FindPath(self, root, expectNumber): # write code here # 定义返回列表 res = [] def dfs(root, target, tmp): if not root: return # 判断搜索终止条件,达到叶节点停止 if target == root.val and not root.left and not root.right: tmp += [root.val] res.append(tmp) # 递归左子树搜索 if root.left: dfs(root.left, target-root.val, tmp + [root.val]) # 递归右子树搜索 if root.right: dfs(root.right, target-root.val, tmp + [root.val]) # 深度优先搜索 dfs(root, expectNumber, []) return resJAVA版本:
import java.util.ArrayList; import java.util.LinkedList; /** public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } } */ public class Solution { //初始化集合 ArrayList res = new ArrayList<>(); LinkedListpath = new LinkedList<>(); public ArrayList FindPath(TreeNode root,int target) { dfs(root, target); return res; } public void dfs(TreeNode root,int tar){ if(root == null){ return; } //将root节点放入路径集合 path.add(root.val); //更新目标值,每放入一个节点,目标值应该相应减去对应节点的值,直到目标值为0 tar -= root.val; //如果目标值减到了0 && 左节点为空 && 右节点为空 证明树已遍历完,此路径为目标路径 if(tar==0 && root.left == null && root.right == null){ res.add(new ArrayList(path)); } // 递归左右子树 dfs(root.left, tar); dfs(root.right, tar); //删除当前节点,在回溯过程中,此节点不在新路径上 path.removeLast(); } }
复杂度分析:
时间复杂度:O(N^2),其中 N 是树的节点数。在最坏情况下,树的上半部分为链状,下半部分为完全二叉树,并且从根节点到每一个叶子节点的路径都符合题目要求。此时,路径的数目为 O(N),并且每一条路径的节点个数也为 O(N),因此要将这些路径全部添加进答案中,时间复杂度为 O(N^2)
空间复杂度:O(N),其中 N 是树的节点数。空间复杂度主要取决于返回列表空间的开销,元素个数不会超过树的节点数
空间复杂度:O(N),其中 N 是树的节点数。空间复杂度主要取决于返回列表空间的开销,元素个数不会超过树的节点数