day25【代码随想录】左叶子之和、找树左下角的值、从中序与后序遍历序列构造二叉树、从中序与前序遍历序列构造二叉树、最大二叉树


前言

1、左叶子之和
2、找树左下角的值
3、从中序与后序遍历序列构造二叉树
4、从中序与前序遍历序列构造二叉树
5、最大二叉树


一、左叶子之和(力扣404)

给定二叉树的根节点 root ,返回所有左叶子之和。
在这里插入图片描述
思路:
判断当前节点是不是左叶子是无法判断的,必须要通过节点的父节点来判断其左孩子是不是左叶子。

if (node->left != NULL && node->left->left == NULL && node->left->right == NULL) {
    左叶子节点处理逻辑
}

1、递归遍历

class Solution {
    int res=0;
    public int sumOfLeftLeaves(TreeNode root) {
        //递归遍历
        if(root==null) return 0;
        postOrder(root);
        return res;
    }
    public void postOrder(TreeNode node){
        if(node==null) return ;
        postOrder(node.left);
        postOrder(node.right);
        if(node.left!=null && node.left.left==null && node.left.right==null){
            res += node.left.val;
        }
    }
}

2、非递归遍历

class Solution {

    public int sumOfLeftLeaves(TreeNode root) {
        //非递归遍历
        int res=0;
        if(root==null) return res;
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode node = stack.pop();
            if(node.left!=null && node.left.left==null && node.left.right==null){
                res += node.left.val;
            }
            if(node.right!=null){
                stack.push(node.right);
            }
            if(node.left!=null){
                stack.push(node.left);
            }
        }
        return res;
    }
}

在这里插入图片描述

二、找树左下角的值(力扣513)

给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。

假设二叉树中至少有一个节点。
在这里插入图片描述
最底层:深度最大
最左边

1、迭代法(层序遍历)

最后一层的第一个值就是所要求的结果值

class Solution {
    public int findBottomLeftValue(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        Queue<TreeNode> que = new LinkedList<>();
        if(root==null) return 0;
        que.offer(root);
        while(!que.isEmpty()){
            int len = que.size();
            List<Integer> itemList = new ArrayList<>();
            while(len-->0){
                TreeNode node = que.poll();
                itemList.add(node.val);
                if(node.left!=null){
                    que.offer(node.left);
                }
                if(node.right!=null){
                    que.offer(node.right);
                }
            }
            res.add(itemList);
        }
        return res.get(res.size()-1).get(0);
    }
}

2、递归法

class Solution {
    private int Deep = -1; //深度
    private int value = 0; //结果值
    public int findBottomLeftValue(TreeNode root) {
       //递归法
       value = root.val;
       findLeftValue(root,0);7
       return value;
    }
    public void findLeftValue(TreeNode root,int deep){
        if(root==null) return ;
        if(root.left==null && root.right==null){
            //叶子节点
            if(deep>Deep){
                value = root.val;
                Deep = deep;
            }
        }
        if(root.left!=null){
            deep++;
            findLeftValue(root.left,deep);
            deep--; //回溯
        }
        if(root.right!=null){
            deep++;
            findLeftValue(root.right,deep);
            deep--; //回溯
        }
    }
}

在这里插入图片描述

三、从中序与后序遍历序列构造二叉树(力扣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.put(inorder[i],i);
        }
        return findNode(inorder,0,inorder.length,postorder,0,postorder.length);
    }
        //切割中序数组  左中序[0,index] [index+1,length-1]
        //切割后序数组  用切割中序数组拿到的左中序数组 来切左后中序
    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;
    }
}

在这里插入图片描述

四、从中序与前序遍历序列构造二叉树(力扣105)

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
在这里插入图片描述
思路:
和第三题基本一致,注意参数的细微差别

class Solution {
    Map<Integer,Integer> map;
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        map = new HashMap<>();
        for(int i=0;i<inorder.length;i++){
            map.put(inorder[i],i);
        }
        return findNode(preorder,0,preorder.length,inorder,0,inorder.length);
    }
    public TreeNode findNode(int[] preorder,int preBegin,int preEnd,int[] inorder,int inBegin,int inEnd){
        if(preBegin >= preEnd || inBegin >= inEnd) return null;
        int rootIndex = map.get(preorder[preBegin]);
        TreeNode root = new TreeNode(inorder[rootIndex]);
        int lenOfLeft = rootIndex - inBegin;
        root.left = findNode(preorder,preBegin+1,preBegin+lenOfLeft+1,inorder,inBegin,rootIndex);
        root.right = findNode(preorder,preBegin+lenOfLeft+1,preEnd,inorder,rootIndex+1,inEnd);
        return root;
    }
}

在这里插入图片描述

五、最大二叉树(力扣654)

给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:

创建一个根节点,其值为 nums 中的最大值。
递归地在最大值 左边 的 子数组前缀上 构建左子树。
递归地在最大值 右边 的 子数组后缀上 构建右子树。
返回 nums 构建的 最大二叉树 。
在这里插入图片描述
思路:
和第三题基本一致,注意参数的细微差别

class Solution {

    public TreeNode constructMaximumBinaryTree(int[] nums) {
        return buildTree(nums,0,nums.length);
    }
    public TreeNode buildTree(int[] nums,int leftIndex,int rightIndex){
        if (rightIndex - leftIndex < 1) {// 没有元素了
            return null;
        }
        if (rightIndex - leftIndex == 1) {// 只有一个元素
            return new TreeNode(nums[leftIndex]);
        }
        int rootIndex = leftIndex;
        int rootValue = nums[rootIndex];

        for(int i =leftIndex;i<rightIndex;i++ ){
            if(nums[i]>rootValue){
                rootValue = nums[i];
                rootIndex = i;
            } 
        }
        TreeNode root = new TreeNode(rootValue);
        root.left=buildTree(nums,leftIndex,rootIndex);
        root.right=buildTree(nums,rootIndex+1,rightIndex);
        return root;
    }
}

在这里插入图片描述


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用class用C++语言编写一段从中序后序遍历构造二叉树并用前序遍历输出的完整代码: ```c++ #include <iostream> #include <vector> using namespace std; class TreeNode { public: int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; class Solution { public: TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { if (inorder.empty() || postorder.empty()) { return nullptr; } return buildTreeHelper(inorder, 0, inorder.size() - 1, postorder, 0, postorder.size() - 1); } private: TreeNode* buildTreeHelper(vector<int>& inorder, int inStart, int inEnd, vector<int>& postorder, int postStart, int postEnd) { if (inStart > inEnd || postStart > postEnd) { return nullptr; } int rootVal = postorder[postEnd]; int rootIndex = -1; for (int i = inStart; i <= inEnd; i++) { if (inorder[i] == rootVal) { rootIndex = i; break; } } int leftSize = rootIndex - inStart; TreeNode* root = new TreeNode(rootVal); root->left = buildTreeHelper(inorder, inStart, rootIndex - 1, postorder, postStart, postStart + leftSize - 1); root->right = buildTreeHelper(inorder, rootIndex + 1, inEnd, postorder, postStart + leftSize, postEnd - 1); return root; } }; void preOrder(TreeNode* root) { if (root == nullptr) { return; } cout << root->val << " "; preOrder(root->left); preOrder(root->right); } int main() { vector<int> inorder = {9, 3, 15, 20, 7}; vector<int> postorder = {9, 15, 7, 20, 3}; Solution s; TreeNode* root = s.buildTree(inorder, postorder); preOrder(root); return 0; } ``` 在上面的代码中,我们首先定义了一个 `TreeNode` 类,表示二叉树的节点。然后定义了一个 `Solution` 类,其中包含了一个 `buildTree` 函数,该函数接受一个中序遍历序列和一个后序遍历序列,并返回由这两个序列构造二叉树的根节点。 在 `buildTree` 函数中,我们首先判断传入的两个序列是否为空,如果有一个为空,则直接返回 `nullptr`,表示构造二叉树为空。接着调用 `buildTreeHelper` 函数进行递归构造二叉树。`buildTreeHelper` 函数的参数分别为中序遍历序列中序遍历序列的起始位置和结束位置、后序遍历序列后序遍历序列的起始位置和结束位置。函数首先判断传入的起始和结束位置是否合法,如果不合法则返回 `nullptr`。然后在后序遍历序列中找到根节点的,以此来区分子树和右子树。然后在中序遍历序列中找到根节点的位置,以此计算出子树的大小。接着递归构造子树和右子树,并将它们分别赋给根节点的右子节点。最后返回根节点。 在 `main` 函数中,我们构造了一个中序遍历序列和一个后序遍历序列,并调用 `buildTree` 函数构造二叉树。然后调用 `preOrder` 函数,用前序遍历的方式输出二叉树的所有节点
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值