【两次过】二叉树中和为某一值的路径

博客给出一个二叉树问题,要求输入二叉树根节点和整数,打印出节点值和为该整数的所有路径,路径从根节点到叶节点。解题思路采用深度优先搜索(DFS)。

题目描述

输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)


解题思路:

dfs

import java.util.ArrayList;
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        
        dfs(root, target, new ArrayList<Integer>(), res);
        
        return res;
    }
    
    private void dfs(TreeNode root, int target, ArrayList<Integer> list, ArrayList<ArrayList<Integer>> res){
        if(root == null)
            return;
        
        list.add(root.val);
        target = target - root.val;
        
        if(root.left == null && root.right == null && target == 0)
            res.add(new ArrayList<Integer>(list));
        
        dfs(root.left, target, list, res);
        dfs(root.right, target, list, res);
        list.remove(list.size()-1);
    }
}

 

<think> 我们正在处理关于完全二叉树路径的问题。根据引用[2],有个示例代码,它根据输入的数组创建完全二叉树,并找出所有路径和等于给定路径。这个代码包括以下几个部分: 1. 定义树节点类 `TreeNode`。 2. 根据列表创建完全二叉树的函数 `creatBTree`。 3. 找出和为某的所有路径的函数 `findPath`,其中使用深度优先搜索(DFS)进行先序遍历,并记录路径。 用户的需求是查找用Python实现完全二叉树路径的代码。我们可以参考引用[2]中的代码,并将其整理为清晰的代码示例。同时,根据引用[3]和[4]中的些概念,我们可以补充说明完全二叉树的性质和路径查找的方法。 注意:引用[2]中的代码假设输入的是层序遍历的数组,其中使用'#'表示空节点(但在示例输入中并没有使用,而是直接使用数字和空格)。然而,在创建二叉树时,它使用了完全二叉树的性质:对于下标为`index`的节点,其左子节点下标为`2*index+1`,右子节点为`2*index+2`。 我们将按照以下步骤编写代码: 1. 定义树节点。 2. 根据数组创建完全二叉树的函数。 3. 实现从根节点到叶子的路径查找,并筛选出路径和等于目标路径。 但是,注意引用[2]中的代码在查找路径时,将路径以列表的列表形式返回,并按路径长度从大到小排序(这个排序不是必须的,可以根据需求调整)。 另外,引用[4]中给出了另种遍历二叉树的方法(求左叶子之和),但我们的重点是路径查找。 下面给出完整的代码示例,并加上必要的注释: ```python # 定义树节点 class TreeNode: def __init__(self, val): self.val = val self.left = None self.right = None # 根据列表创建完全二叉树 def createBTree(data, index): # 如果索引超出列表长度,或者该位置为'#'(代表空节点),则返回None if index >= len(data) or data[index] == '#': return None # 创建当前节点 node = TreeNode(data[index]) # 递归创建左子树和右子树 node.left = createBTree(data, 2 * index + 1) node.right = createBTree(data, 2 * index + 2) return node # 找出和为某的所有路径(从根到叶子) def findPath(root, target): # 用于存储所有符合条件的路径 result = [] # 当前路径 path = [] # 递归辅助函数 def dfs(node, current_sum): if not node: return # 将当前节点加入路径 path.append(int(node.val)) current_sum += int(node.val) # 如果是叶子节点,检查路径和是否等于目标 if not node.left and not node.right: if current_sum == target: result.append(path[:]) # 注意要用切片复制当前路径 # 递归遍历左右子树 dfs(node.left, current_sum) dfs(node.right, current_sum) # 回溯,从路径中移除当前节点 path.pop() dfs(root, 0) # 返回结果,可以按需求排序,这里按路径长度从大到小排序(原代码做法) return sorted(result, key=len, reverse=True) # 主函数 if __name__ == "__main__": # 输入目标 target = int(input("请输入目标: ")) # 输入节点,用空格分隔,空节点用'#'表示(但注意完全二叉树的表示,通常空节点在末尾可以省略,但中间空节点需用'#'占位) data = input("请输入节点(空格分隔): ").split() # 创建完全二叉树 root = createBTree(data, 0) # 查找路径 paths = findPath(root, target) print("所有路径和等于{}的路径:".format(target)) for p in paths: print(p) ``` 注意: 1. 该代码假设输入的数据是字符串,需要转换为整数。如果节点为非数字,则需要进行调整。 2. 在创建二叉树时,如果某个位置是空节点,则输入'#',否则输入节点的。但是,在完全二叉树中,空节点通常出现在末尾,所以中间非空节点后的空节点需要用'#'占位,以保证位置的正确性。 3. 路径查找使用深度优先遍历(DFS),并在到达叶子节点时检查路径和。 4. 在递归回溯时,需要将当前节点从路径中移除(即`path.pop()`)。 示例输入和输出: 输入目标:22 输入节点:5 4 8 11 # 13 4 7 2 # # 5 1 (注意:这里用空格分隔,其中'#'表示空节点) 这个输入对应的二叉树如下(示例): 5 / \ 4 8 / / \ 11 13 4 / \ / \ 7 2 5 1 那么路径和为22的路径有:[5,4,11,2] 和 [5,8,4,5] 但是注意,我们的代码在创建树时,需要严格按照完全二叉树的形式,所以输入数组应该是层序遍历的,并且中间空节点用'#'占位。在这个例子中,输入数组应该是:['5','4','8','11','#','13','4','7','2','#','#','5','1']。 运行代码后,将输出这两条路径。 此外,我们还可以参考引用[3]中提到的完全二叉树可以用非嵌套列表(数组)实现,因为完全二叉树具有性质:节点i的左子节点在2i,右子节点在2i+1(这里索引从1开始)。但在我们的代码中,索引是从0开始的,所以左子节点在2*i+1,右子节点在2*i+2。 以上代码和说明应该能够满足用户的需求。 §§相关问题§§ 1. 如何优化查找二叉树中和为某路径的算法? 2. 在非完全二叉树中如何实现路径查找? 3. 完全二叉树在数据结构中还有哪些应用? </think> 以下是使用Python实现完全二叉树路径查找的代码,重点解决"从根节点到叶子节点路径和等于给定"的问题: ```python # 定义树节点类 class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = int(val) # 确保为整数类型 self.left = left self.right = right # 根据列表创建完全二叉树 def create_complete_binary_tree(data, index=0): """ 根据层序遍历列表创建完全二叉树 :param data: 层序遍历的节点列表 (空节点用'#'表示) :param index: 当前节点在列表中的索引 :return: 构建好的二叉树根节点 """ if index >= len(data) or data[index] == '#': return None # 创建当前节点 node = TreeNode(data[index]) # 递归创建左右子树 (利用完全二叉树的性质) node.left = create_complete_binary_tree(data, 2 * index + 1) node.right = create_complete_binary_tree(data, 2 * index + 2) return node # 查找所有路径和等于目标路径 def find_paths_with_sum(root, target_sum): """ 查找所有从根到叶子节点路径和等于目标路径 :param root: 二叉树根节点 :param target_sum: 目标路径和 :return: 符合条件的路径列表 """ if not root: return [] result = [] # 存储所有符合条件的路径 def dfs(node, current_path, current_sum): # 将当前节点添加到路径 current_path.append(node.val) current_sum += node.val # 如果是叶子节点且路径和等于目标 if not node.left and not node.right: if current_sum == target_sum: result.append(current_path.copy()) # 递归遍历左右子树 if node.left: dfs(node.left, current_path, current_sum) if node.right: dfs(node.right, current_path, current_sum) # 回溯:移除当前节点 current_path.pop() dfs(root, [], 0) return result # 主函数 if __name__ == "__main__": # 示例输入:目标 22,层序遍历序列 [5,4,8,11,'#',13,4,7,2,'#','#',5,1] target = 22 data = input("请输入层序遍历序列(空格分隔,空节点用#表示): ").split() target = int(input("请输入目标路径和: ")) # 构建完全二叉树 root = create_complete_binary_tree(data) # 查找路径 paths = find_paths_with_sum(root, target) # 输出结果 if paths: print(f"找到 {len(paths)} 条路径和为 {target} 的路径:") for i, path in enumerate(paths, 1): print(f"路径 {i}: {' -> '.join(map(str, path))}") else: print(f"未找到路径和为 {target} 的路径") ``` ### 代码说明 1. **TreeNode类**: - 表示二叉树节点,包含和左右子节点指针 - 自动转换为整数类型,确保计算正确性 2. **create_complete_binary_tree函数**: - 利用完全二叉树的性质:节点i的左子节点在$2i+1$,右子节点在$2i+2$ - 支持空节点表示(使用'#'占位) - 时间复杂度:$O(n)$,每个节点只访问次 3. **find_paths_with_sum函数**: - 使用深度优先搜索(DFS)遍历所有路径 - 采用回溯法记录当前路径 - 到达叶子节点时检查路径和是否等于目标 - 时间复杂度:$O(n)$,每个节点访问次 4. **输入输出示例**: ``` # 输入 请输入层序遍历序列(空格分隔,空节点用#表示): 5 4 8 11 # 13 4 7 2 # # 5 1 请输入目标路径和: 22 # 输出 找到 2 条路径和为 22 的路径: 路径 1: 5 -> 4 -> 11 -> 2 路径 2: 5 -> 8 -> 4 -> 5 ``` ### 完全二叉树的性质 - 除最后层外,其他层节点数达到最大 - 最后层节点从左到右连续排列 - 节点$i$的: - 父节点索引:$\lfloor (i-1)/2 \rfloor$ - 左子节点索引:$2i+1$ - 右子节点索引:$2i+2$ ### 应用场景 1. 优先队列实现(二叉堆) 2. 堆排序算法 3. 高效优先级调度系统 4. 图算法中的最短路径计算(如Dijkstra算法)[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值