path_sum2

本文介绍了一种寻找二叉树中所有从根节点到叶子节点路径的算法,这些路径上的节点值之和等于给定的目标值。通过递归方法实现,并使用SuperNode辅助结构来记录路径。

题目描述

Given a binary tree and a sum, find all root-to-leaf paths where each path’s sum equals the given sum.

For example:
Given the below binary tree and sum = 22,

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

return

[

[5,4,11,2],

[5,8,4,5]

]

解题思路

做此题前可以先尝试path_sum,判断二叉树是否存在一条根节点到叶子节点路径使得数值和等于sum,这里则是求出所有的这样的路径集合。

原先的递归关键点是对左右儿子节点递归,左右有一个返回true,当前函数就返回true,现在我们是计算路径,所以每个节点都需要对左右子树遍历,对于符合条件的路径加入到结果结合中。

为了找到一条路径,我定义了一个SuperNode,可以记录其前驱,数据结构如下:

 public class SuperNode {
     int val;
     SuperNode pre;//指向前驱节点
     public SuperNode(int x) 
        { 
            val = x; 
            pre = null;
        }
 }

每次经过一个节点,我们都建立一个supernode sn,标记该节点的val,以及其前驱,如果找到一条符合条件的通路,则把这个sn加入到我们的节点结合List中,最后对list遍历,对其中每个元素sn,进行找前驱的方式,可以得到一条路径,然后放到路径集合中。

详细代码

//path sum2
public List<List<Integer>> pathSum(TreeNode root, int sum) 
{
    List<List<Integer>> resultLists = new ArrayList<>();//结果路径集合
    List<SuperNode> superNodes = new ArrayList<>();//supernodes 集合,每个supernode可以生成一条路径。
    if(root == null)
    {
        return resultLists;
    }
    findPathSum(root, sum, new SuperNode(root.val), superNodes);
    for(SuperNode sn:superNodes)//对supernodes进行遍历,每个node生成一条路径
    {
        List<Integer> lists = new LinkedList<>(); //利用链表插入提高效率
        while(sn != null)
        {
            lists.add(0, sn.val);
            sn = sn.pre;
        }
        resultLists.add(lists);
    }
    return resultLists;
}

 public class SuperNode {
     int val;
     SuperNode pre;//指向前驱节点
     public SuperNode(int x) 
        { 
            val = x; 
            pre = null;
        }
 }

//找到指定路径 返回null为没有 否则可以根据node遍历得到逆序
public void findPathSum(TreeNode root, int sum, SuperNode sn, List<SuperNode> superNodes) {
    if(root == null)
    {
        //空树  结束条件之一
        return;
    }
    else 
    {
        if(root.left==null && root.right==null)
        {
            //叶子节点 left right都为空
            if(sum== root.val)
            {
                superNodes.add(sn);
                return;
            }
            else 
            {
                return;
            }
        }
        else 
        {
            //非叶子结点
            if(root.left != null)
            {
                SuperNode node = new SuperNode(root.left.val);
                node.pre = sn;
                findPathSum(root.left, sum-root.val,node, superNodes);

            }
            if(root.right != null)
            {
                SuperNode node = new SuperNode(root.right.val);
                node.pre = sn;
                findPathSum(root.right, sum-root.val,node, superNodes);

            }

        }
    }
}
在这段代码中,`class Node:` 及其 `__init__` 方法的定义用于创建 **RRT* 算法中的节点对象**,表示无人机在二维空间中某一状态的完整信息。该类是路径规划算法(特别是基于树结构的 RRT*)的核心数据结构。 以下是对其功能和作用的详细分析: --- ### 类功能概述 `Node` 类封装了无人机在飞行过程中的一个“状态点”,不仅包含位置信息,还包括运动方向、路径代价、累计风险、路径长度以及父节点引用等关键属性,为后续的路径搜索、代价评估与最优路径回溯提供支持。 --- ### `__init__` 方法参数解析 ```python def __init__(self, x, y, theta, cost, prob_sum, path_len, parent=None): ``` - **`x`, `y`**: 表示当前节点的二维坐标(单位:米),即无人机在此时刻的空间位置。 - **`theta`**: 当前运动方向的角度(以弧度表示),用于模拟无人机具有航向约束的动力学特性(如不能瞬间转向)。这在计算下一节点方向和转弯限制时至关重要。 - **`cost`**: 定义为“单位距离被发现概率”(注释说明),实际是路径的平均风险代价(`prob_sum / path_len`)。RRT* 在扩展过程中会依据此值选择更优路径进行重连优化。 - **`prob_sum`**: 从起点到当前节点的累计“被发现概率”乘以距离的积分(可理解为总风险值)。它是构建 `cost` 的基础。 - **`path_len`**: 从起点到当前节点的路径总长度(单位:米)。用于判断是否超出最大航程(`MAX_RANGE`),也用于归一化风险值得到单位距离代价。 - **`parent`**: 指向父节点的引用,构成树形结构。通过不断追溯 `parent`,可以在找到目标后重构出完整路径。 --- ### 属性用途详解 | 属性名 | 用途 | |-------------|------| | `self.x`, `self.y` | 路径可视化、距离计算、地形查询的基础坐标 | | `self.theta` | 控制无人机前进方向,确保满足最大转向角约束(`MAX_ANGLE_CHANGE`) | | `self.cost` | RRT* 中用于比较不同路径优劣的核心指标;越低越好 | | `self.prob_sum` | 累计风险,参与代价更新,在路径重连接时决定是否替换现有路径 | | `self.path_len` | 判断是否超航程、计算平均代价、插值输出路径点数的依据 | | `self.parent` | 实现路径回溯的关键,最终通过 `while current: ... current = current.parent` 重建路径 | --- ### 在整体算法中的作用 1. **构建搜索树**: - 所有生成的有效节点都保存在 `nodes` 列表中。 - 每个新节点通过 `parent` 连接到树上,形成一棵由起点向外生长的探索树。 2. **支持代价传播与路径优化(RRT* 特性)**: - 新节点插入后,算法理论上应检查其邻域内其他节点是否可通过它获得更低代价(即重新布线),虽然本实现未完全写出 rewire 步骤,但 `cost` 字段为此预留了结构。 3. **实现路径回溯**: - 成功到达目标区域的节点被加入 `goal_nodes`,最后选择 `cost` 最小的作为最优终点。 - 使用 `parent` 链逐级回溯,生成从起点到终点的完整路径。 4. **满足动力学与环境约束**: - `theta` 和转向逻辑保证路径平滑且符合最小转弯半径假设; - `path_len` 限制航程; - 结合 `check_height_constraint` 确保飞行安全高度。 --- ### 示例场景说明 当算法在迭代中生成一个新的飞行状态时,就会实例化一个 `Node` 对象: ```python new_node = Node(new_x, new_y, new_theta, new_cost, new_prob_sum, new_path_len, nearest_node) ``` 这个节点记录了当前位置、朝向、已飞距离、累积风险、单位风险代价及其来源(`nearest_node`),成为继续扩展或最终路径的一部分。 --- ### 总结 `Node` 类的设计体现了对无人机路径规划问题的多维建模能力:不仅仅是几何路径最短,还综合考虑了**飞行方向连续性、探测风险最小化、航程限制和地形避障**等多个现实因素。它是整个 RRT* 算法能够生成安全、可行且相对最优路径的数据基石。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值