Day 15 513.找树左下角的值 112. 路径总和 106.从中序与后序遍历序列构造二叉树

32 阅读3分钟

513. 找树左下角的值 - 力扣(LeetCode)

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

假设二叉树中至少有一个节点。

自己AC的方法,逻辑比较混乱

class Solution {
private:
    int maxdepth;
    int curdepth = 1;//当前深度
    int res;
    int flag = 0;
public:
    int findBottomLeftValue(TreeNode* root) {
        maxdepth = gethigh(root);
        traverse(root);
        return res;
    }

    void traverse(TreeNode* node){
        if(flag==1) return;
        if(node == nullptr) return;
        if(!node->left&&!node->right&&curdepth == maxdepth){
            res = node->val;
            flag = 1;
        }
        if(node->left){
            curdepth++;
            if(curdepth == maxdepth){
                res = node->left->val;
                curdepth--;
                flag = 1;
                return;
            }
            traverse(node->left);
            curdepth--;
        }
        if(node->right){
            curdepth++;
            if(curdepth == maxdepth){
                res = node->right->val;
                curdepth--;
                flag = 1;
                return;
            }
            traverse(node->right);
            curdepth--;
        }
    }

    int gethigh(TreeNode* node){
        if(node == nullptr) return 0;
        int L = gethigh(node->left);
        int R = gethigh(node->right);
        return max(L,R)+1;
    }
};

路径求和问题

把+/-融入递归/回溯的过程,复杂度为O(N)O(N)

找到路径后for循环累加,复杂度为O(N2)O(N^2)

112. 路径总和 - 力扣(LeetCode)

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

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

自己AC啦

class Solution {
private:
    vector<int> path;
    bool res;
public:
    bool hasPathSum(TreeNode* root, int targetSum) {
        traverse(root,targetSum);
        return res;
    }
    void traverse(TreeNode* node,int targetSum){
        if(res==1) return;
        if(node == nullptr) return;
        path.push_back(node->val);
        if(!node->left&&!node->right){//遇到叶子节点判断和是否为tar
            int sum = 0;
            for(int i:path){
                sum+=i;
            }
            if(sum==targetSum) res =1;
        }
        if(node->left){
            traverse(node->left,targetSum);
            path.pop_back();
        }
        if(node->right){
            traverse(node->right,targetSum);
            path.pop_back();
        }
    }
};

113. 路径总和 II - 力扣(LeetCode)

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

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

class Solution {
private:
    vector<int> path;
    vector<vector<int>> allpath;
public:
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        traverse(root,targetSum);
        return allpath;
    }
    void traverse(TreeNode* node,int targetSum){
        if(node == nullptr) return;
        path.push_back(node->val);
        if(!node->left&&!node->right){//遇到叶子节点判断和是否为tar
            int sum = 0;
            for(int i:path){
                sum+=i;
            }
            if(sum==targetSum){
                allpath.push_back(path);
            } 
        }
        if(node->left){
            traverse(node->left,targetSum);
            path.pop_back();
        }
        if(node->right){
            traverse(node->right,targetSum);
            path.pop_back();
        }
    }
};

106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)

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

分解问题思想。根据给的数组创立根节点,并拆分数组,再用拆分后的数组调用buildTree函数创立左子树、右子树并接在根节点下。最后返回根节点即可。 106.中序后序构造二叉树.png

class Solution {
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        vector<int>sub1_in;
        vector<int>sub2_in;
        vector<int>sub1_post;
        vector<int>sub2_post;

        if(postorder.empty()) return nullptr;
        int mid = postorder.back();//后序的back是根节点
        postorder.pop_back();
        TreeNode* root = new TreeNode(mid);
        //根据mid拆中序
        for(int i = 0;i<inorder.size();i++){
            if(inorder[i]==mid){ //找到分割位置
                //i不在数组第一个,存在左子树
                if(i!=0) copy(inorder.begin(),inorder.begin()+i,back_inserter(sub1_in));
                //i不在数组最后一个,存在右子树
                if(i!=inorder.size()-1) copy(inorder.begin()+(i+1),inorder.end(),back_inserter(sub2_in));
            }
        }
        //根据拆出来的中序大小,拆后序
        if(!sub1_in.empty()){  //sub1_in非空,有左子树
            int size = sub1_in.size();
            copy(postorder.begin(),postorder.begin()+size,back_inserter(sub1_post));
        }
        root->left = buildTree(sub1_in,sub1_post);
        if(!sub2_in.empty()){  //sub2_in非空,有右子树
            int size = sub2_in.size();
            copy(postorder.end()-size,postorder.end(),back_inserter(sub2_post));
        }
        root->right = buildTree(sub2_in,sub2_post);
        return root;
    }
};