【剑指offer】34. 二叉树中和为某一值的路径

130 阅读2分钟

题目描述

在这里插入图片描述

在这里插入图片描述

// 输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整
// 数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点
// 形成一条路径。

// 输入一颗二叉树的根节点和一个整数,按字典序打印出二叉树中结点值
// 的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到
// 叶结点所经过的结点形成一条路径。

题解

// 前序遍历,用数组path记录遍历元素,遍历到元素就存进去,回溯父结点就删掉元素。
// 遍历同时要记录遍历元素的和是否等于target(大于小于都没用),由于题目
// 的路径必须要从根节点到叶节点,如果记录的遍历元素之和与target相等,
// 还需要判断当前遍历结点是否是叶节点(没有左右子树)。

// 力扣
// 执行用时:1 ms, 在所有 Java 提交中击败了100.00%的用户
// 内存消耗:38.8 MB, 在所有 Java 提交中击败了55.26%的用户
class Solution {
	List<List<Integer>> res = new ArrayList<>();  // 答案保存组res

    public List<List<Integer>> pathSum(TreeNode root, int sum) {
		ArrayList<Integer> path = new ArrayList<Integer>();  // 单条路径初始化
		recur(root, sum, path);  // 开始前序遍历
		return res;
    }
	
	private void recur(TreeNode root, int target, ArrayList<Integer> path) {
		if (root == null)  // 根据前序遍历,如果走到头了,return
			return; 
		path.add(root.val);  //当前遍历元素root.val存入路径数组path
		// 令target减去遍历的每一个元素root.val(减为0说明当前路径之和为target)
		target -= root.val;  
		// 如果路径之和为target,且路径重点是叶节点,把路径path保存入res
		if ((target == 0) && (root.left == null) && (root.right == null)) 
			// 这里必须重新new一下,否则只是将path对象加进了res
			// path改变了res对象也会改变,重新new相当于复制了一个path,
			// 对象已经不同了
			res.add(new ArrayList<>(path));  
		else {  // 否则,就按照前序遍历走下去
			recur(root.left, target, path);
			recur(root.right, target, path);
		}
		// 前序遍历回溯,将路径path的末尾点删掉表示路径回溯(到父结点
		path.remove(path.size() - 1);
	}
}


// 牛客
// 运行时间:14ms
// 占用内存:9840k
import java.util.ArrayList;
public class Solution {
    ArrayList<ArrayList<Integer>> res = new ArrayList<>();
	
    public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
        ArrayList<Integer> path = new ArrayList<>();
        recur(root, target, path);
        return res;
    }
    
    private void recur(TreeNode root, int target, ArrayList<Integer> path) {
        if (root == null)
            return;
        target -= root.val;
        path.add(root.val);;
        if ((target == 0) && (root.left == null) && (root.right == null))
            res.add(new ArrayList<>(path));
        else {
            recur(root.left, target, path);
            recur(root.right, target, path);
        }
        path.remove(path.size() - 1);
    }
}