二叉树路径和为一固定值

二叉树类题目,第一反应肯定就是使用递归(dfs)。这道题也不例外。

还是先给出我的代码。主要注意数组的引用性。所以每次都要去掉尾数。

并在最后放入结果集中时,执行深copy。

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>> result = new ArrayList<>();
        ArrayList<Integer> array = new ArrayList<>();
        find(root,target,result,array);
        
        return result;
    }
    void find(TreeNode root,int target,ArrayList<ArrayList<Integer>> result,ArrayList<Integer> array){
        if(null == root){
           return;
        }
        array.add(root.val);
        target-=root.val;
        if(0 == target && null == root.left && null == root.right){
            result.add(new ArrayList<>(array)); //直接赋值是引用赋值,指向相同对象。array最终回到顶层就只有一个10。
            return;
        }
        
        if(null !=root.left){
            find(root.left,target,result,array);
            array.remove(array.size() -1);
        }
        if(null != root.right){
            find(root.right,target,result,array);
            array.remove(array.size() -1);
        }
        
    }
}

利用类变量的简化版:

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 {
    ArrayList<ArrayList<Integer>> result = new ArrayList<>();
    ArrayList<Integer> array = new ArrayList<>();
    public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
         if(null == root){
           return result;
        }
        array.add(root.val);
        target-=root.val;
        if(0 == target && null == root.left && null == root.right){
            result.add(new ArrayList<>(array)); //直接赋值是引用赋值,指向相同对象。array最终回到顶层就只有一个10。
        }
        FindPath(root.left,target);
        FindPath(root.right,target);
        array.remove(array.size() -1);
        return result;
    }
}

非递归法:注意牛客的编译器C++越界不会报错。但是java肯定会抛异常的。一定小心数组越界。

import java.util.ArrayList;
import java.util.Stack;
/**
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>> result = new ArrayList<>();
         if(null == root){
           return result;
        }
        ArrayList<Integer> array = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        TreeNode cur = root;
        TreeNode last = null;
        int sum=0;
        while(!stack.isEmpty()){
            if(null != cur){
                stack.push(cur);
                array.add(cur.val);
                sum += cur.val;
                if(target == sum && null == cur.left && null == cur.right){
                    result.add(new ArrayList<Integer>(array));
                }
                cur = cur.left;
            }else{
                TreeNode temp = stack.peek();
                if(null != temp.right && temp.right != last){
                    cur = temp.right;
                }else{
                    last = temp;
                    stack.pop();
                    if(array.size() >0){
                        array.remove(array.size() - 1);
                    }
                    sum -= temp.val;
                }
            }
            
        }
        return result;
    }
}

<think>好的,我现在需要帮助用户解决关于C语言实现二叉树路径搜索的问题。用户希望查找指定节点路径的算法实现。首先,我需要回顾二叉树的基本操作,特别是路径搜索相关的知识。 根据用户提供的引用内容,他们之前接触过如何计算叶子节点二叉树深度,使用了递归的方法。比如引用[1]中的bitree_count函数引用[2]中的LeafNode函数,都是通过递归遍历左右子树来累加结果。因此,路径搜索可能也需要类似的递归方法,但需要记录路径上的节点。 接下来,我需要考虑路径搜索的具体实现步骤。首先,如何判断当前节点是否为目标节点?需要比较节点的某个值,比如用户提到的data字段。然后,在遍历过程中,需要记录从根节点到当前节点的路径。这可以通过个数组或者链表来保存路径节点,每次进入子树时将当前节点加入路径,回溯时再移除。 可能出现的问题包括:如何处理路径的动态存储?如何确保路径的正确性?例如,在递归调用时,如果使用全局变量可能会有并发问题,而使用参数传递可能会更安全。因此,可以设计个辅助函数,接受当前节点、目标值、路径数组当前深度作为参数,通过指针或数组索引来维护路径。 还需要考虑递归终止条件:当节点为空时返回失败;当节点值匹配时,记录当前路径并返回成功。在左右子树递归搜索时,如果找到路径则提前返回,避免不必要的遍历。 另外,用户提供的示例代码中使用了结构体bitree,包含data、lchrch字段,因此需要保持结构体的致性。路径的存储可以使用静态数组,但需要注意数组大小的限制,或者动态分配内存。不过,为了简化示例,可能先使用固定大小的数组,并处理可能的溢出情况。 最后,需要测试代码的正确性,比如构造二叉树,调用函数查找某个节点,验证返回的路径是否正确。同时,考虑路径不存在的情况,函数应返回0或相应状态。 总结步骤: 1. 定义二叉树结构体。 2. 编写路径查找函数,使用递归遍历。 3. 在递归过程中维护路径数组。 4. 找到目标节点后保存路径并返回。 5. 处理左右子树的递归调用,回溯时调整路径。 现在需要将这些思路转化为具体的C代码,并确保语法正确,逻辑清晰。同时,根据用户的要求,生成相关问题,帮助用户进步学习。</think>### C语言实现二叉树路径搜索算法 #### 算法思路 1. **递归遍历**:采用前序遍历方式搜索目标节点 2. **路径记录**:使用数组存储当前路径节点索引 3. **回溯机制**:当子树搜索失败时回退路径记录 #### 实现代码 ```c #include <stdio.h> #include <stdlib.h> typedef struct bitree { int data; struct bitree* lch; struct bitree* rch; } bitree; // 路径查找辅助函数 int find_path(bitree* node, int target, int path[], int* depth) { if (!node) return 0; // 记录当前节点 path[(*depth)++] = node->data; // 找到目标节点 if (node->data == target) return 1; // 递归查找左子树 if (find_path(node->lch, target, path, depth)) return 1; // 递归查找右子树 if (find_path(node->rch, target, path, depth)) return 1; // 回溯:当前路径不包含目标节点 (*depth)--; return 0; } // 路径查找接口函数 void get_node_path(bitree* root, int target) { int path[100] = {0}; // 假设树深度不超过100 int depth = 0; if (find_path(root, target, path, &depth)) { printf("路径长度: %d\n路径节点: ", depth); for (int i = 0; i < depth; i++) { printf("%d->", path[i]); } printf("END\n"); } else { printf("未找到目标节点\n"); } } ``` #### 算法特点 1. **时间复杂度**:$O(n)$,最坏情况遍历所有节点 2. **空间复杂度**:$O(h)$,h为二叉树高度[^1] 3. **实现要点**: - 使用前序遍历保证路径顺序 - 通过递归调用栈实现自动回溯 - 路径数组存储节点访问序列
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值