LeetCode 112. 路径总和,113. 路径总和ii,106.从中序与后序遍历序列构造二叉树,105.从前序与中序遍历序列构造二叉树

这篇文章介绍了如何在二叉树中寻找路径总和等于给定值的路径,提供了两种不同的解决方案,一种是递归方法,另一种是迭代方法。同时,文章还展示了如何根据中序和后序遍历以及先序和中序遍历序列来构建二叉树的算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

112. 路径总和


给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。

 /**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if(root == null) return false;
        return travel(root, targetSum - root.val);
    }
    public boolean travel(TreeNode root, int targetSum){
        if(root.left == null && root.right == null && targetSum == 0) return true;
        if(root.left == null && root.right == null && targetSum != 0) return false;
        if(root.left != null){
            targetSum -= root.left.val;
            if(travel(root.left, targetSum))
            return true;
            targetSum += root.left.val;
        }
        if(root.right != null){
            targetSum -= root.right.val;
            if(travel(root.right, targetSum))
            return true;
            targetSum += root.right.val;
        }
        return false;
    }
}
  • 迭代

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if(root == null) return false;
        Stack<TreeNode> stack1 = new Stack<>();
        Stack<Integer> stack2 = new Stack<>();
        stack1.push(root);
        stack2.push(root.val);
        while(!stack1.isEmpty()){
            TreeNode node = stack1.pop();
            int sum = stack2.pop();
            if(node.left == null && node.right == null && sum == targetSum) return true;
            if(node.left != null){
                stack1.push(node.left);
                stack2.push(sum + node.left.val);
            }
            if(node.right != null){
                stack1.push(node.right);
                stack2.push(sum + node.right.val);
            }
        }
        return false;
    }
}

113. 路径总和ii


给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。

叶子节点 是指没有子节点的节点。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> path = new LinkedList<>();
        if(root == null) return res;
        travel(root, targetSum, res, path);
        return res;

    }
    public void travel(TreeNode root, int targetSum, List<List<Integer>> res, List<Integer> path){
        path.add(root.val);
        if(root.left == null && root.right == null){
            if(targetSum - root.val == 0){
                res.add(new ArrayList<>(path));
            }
            return;
        }
        if(root.left != null){
            travel(root.left, targetSum - root.val , res, path);
            path.remove(path.size() - 1);

        }
        if(root.right != null){
            travel(root.right, targetSum - root.val , res, path);
            path.remove(path.size() - 1);
        }

    }
}
  • 官方

 class solution {
    public List<List<Integer>> pathsum(TreeNode root, int targetsum) {
        List<List<Integer>> res = new ArrayList<>();
        if (root == null) return res; // 非空判断

        List<Integer> path = new LinkedList<>();
        preorderdfs(root, targetsum, res, path);
        return res;
    }

    public void preorderdfs(TreeNode root, int targetsum, List<List<Integer>> res, List<Integer> path) {
        path.add(root.val);
        // 遇到了叶子节点
        if (root.left == null && root.right == null) {
            // 找到了和为 targetsum 的路径
            if (targetsum - root.val == 0) {
                res.add(new ArrayList<>(path));
            }
            return; // 如果和不为 targetsum,返回
        }

        if (root.left != null) {
            preorderdfs(root.left, targetsum - root.val, res, path);
            path.remove(path.size() - 1); // 回溯
        }
        if (root.right != null) {
            preorderdfs(root.right, targetsum - root.val, res, path);
            path.remove(path.size() - 1); // 回溯
        }
    }
}

106.从中序与后序遍历序列构造二叉树


给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

class Solution {
    Map<Integer, Integer> map;  // 方便根据数值查找位置
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        map = new HashMap<>();
        for (int i = 0; i < inorder.length; i++) { // 用map保存中序序列的数值对应位置
            map.put(inorder[i], i);
        }

        return findNode(inorder,  0, inorder.length, postorder,0, postorder.length);  // 前闭后开
    }

    public TreeNode findNode(int[] inorder, int inBegin, int inEnd, int[] postorder, int postBegin, int postEnd) {
        // 参数里的范围都是前闭后开
        if (inBegin >= inEnd || postBegin >= postEnd) {  // 不满足左闭右开,说明没有元素,返回空树
            return null;
        }
        int rootIndex = map.get(postorder[postEnd - 1]);  // 找到后序遍历的最后一个元素在中序遍历中的位置
        TreeNode root = new TreeNode(inorder[rootIndex]);  // 构造结点
        int lenOfLeft = rootIndex - inBegin;  // 保存中序左子树个数,用来确定后序数列的个数
        root.left = findNode(inorder, inBegin, rootIndex,
                            postorder, postBegin, postBegin + lenOfLeft);
        root.right = findNode(inorder, rootIndex + 1, inEnd,
                            postorder, postBegin + lenOfLeft, postEnd - 1);

        return root;
    }
}
  • 自己写的

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    Map<Integer, Integer> map = new HashMap<>();
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        for(int i = 0; i < inorder.length; i++){
            map.put(inorder[i], i);
        }
        return findNode(inorder, 0, inorder.length, postorder, 0, postorder.length);
    }
    //统一采用前闭后开
    public TreeNode findNode(int[] inorder, int inFirst, int inLast, int[] postorder, int postFirst, int postLast){
        if(inLast <= inFirst || postFirst >= postLast) return null;
        int posit = map.get(postorder[postLast - 1]);//中序位置
        TreeNode node = new TreeNode(inorder[posit]);
        int lenOfLeft = posit - inFirst;
        node.left = findNode(inorder, inFirst, posit, postorder, postFirst, postFirst + lenOfLeft);
        node.right = findNode(inorder, posit + 1, inLast, postorder, postFirst + lenOfLeft, postLast - 1);
        return node;

    }
}

105.从前序与中序遍历序列构造二叉树


给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    Map<Integer, Integer> map = new HashMap<>();
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        for(int i = 0; i < inorder.length; i++){
            map.put(inorder[i], i);
        }
        return find(preorder, 0, preorder.length, inorder, 0, inorder.length);
    }
    //包前不包后
    public TreeNode find(int[] preorder, int preFirst, int preLast, int[] inorder, int inFirst, int inLast){
        if(preLast <= preFirst || inLast <= inFirst) return null;
        //获取位置
        int posit = map.get(preorder[preFirst]);
        TreeNode node = new TreeNode(inorder[posit]);
        int resLen = inLast - posit;
        node.left = find(preorder, preFirst + 1, preLast - resLen + 1, inorder, inFirst, posit);
        node.right = find(preorder, preLast - resLen + 1, preLast, inorder, posit + 1, inLast);
        return node;

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值