代码随想录算法训练营第十八天 | 题目513.找树左下角的值 题目 112. 路径总和 题目113.路径总和ii 题目106.从中序与后序遍历序列构造二叉树 题目105.从前序与中序遍历序列构造二叉树

513.找树左下角的值

迭代法:层序遍历

class Solution {
public:
    //层序遍历
    int findBottomLeftValue(TreeNode* root) {
        if(root == NULL)return 0;
        queue<TreeNode*>que;
        que.push(root);
        int result;
        while(!que.empty()){
            int size = que.size();
            for(int i = 0; i < size; i++){
                TreeNode* node;
                node = que.front();
                que.pop();
                //记录最后一行的第一个元素
                if(i == 0) result = node->val;
                if(node->left != NULL) que.push(node->left);
                if(node->right != NULL)que.push(node->right);
            }
        }
        return result;
    }
};

递归法:

class Solution {
public:
    //递归法
    int maxDepth = INT_MIN;
    int result;
    void traversal(TreeNode* node, int depth){

        //判断终止条件
        if(node->left == NULL && node->right == NULL){
            if(depth > maxDepth){
                maxDepth = depth;
                result = node->val;
            }
            return; //结束函数的执行,返回函数调用点
        }
        if(node->left){
            depth++;
            traversal(node->left, depth);
            depth--;
        }
        if(node->right){
            depth++;
            traversal(node->right, depth);
            depth--;  //结束函数的执行,返回函数调用点
        }
        return;
    }
    int findBottomLeftValue(TreeNode* root) {
        if(root == NULL)return 0;
        traversal(root, 1);
        return result;
    }
};

112. 路径总和

递归法:

class Solution {
public:
    bool traversal(TreeNode* root, int count) {
        if(root->left == NULL && root->right == NULL && count == 0) return true;
        if(root->left == NULL && root->right == NULL)return false;
        if(root->left){
            count -= root->left->val;
            if(traversal(root->left, count))return true;
            count += root->left->val;
        }
        if(root->right){
            count -= root->right->val;
            if(traversal(root->right, count))return true;
            count += root->right->val;
        }
        return false;
    }
    bool hasPathSum(TreeNode* root, int targetSum){
        if(root == NULL)return false;
        return traversal(root, targetSum - root->val);
    }
};

迭代法:在迭代法中,要记录从根节点到当前节点路径的值的总和。

class Solution {
public:
    bool hasPathSum(TreeNode* root, int targetSum) {
        if(root == nullptr)return false;
        stack<pair<TreeNode*, int>> st;
        st.push(pair<TreeNode*, int>(root, root->val));
        while(!st.empty()){
            pair<TreeNode*, int> node = st.top();
            st.pop(); 
            //如果该节点是叶子结点,同时该路径上节点值的总和等于目标和,返回真
            if(node.first->left == nullptr && node.first->right == nullptr && targetSum == node.second)return true;
            //将右孩子压入栈中
            if(node.first->right){
                st.push(pair<TreeNode*, int>(node.first->right, node.second + node.first->right->val));
            }
            if(node.first->left){
                st.push(pair<TreeNode*, int>(node.first->left, node.second + node.first->left->val));
            }
        }
        return false;

    }
};

113.路径总和ii

class Solution {
public:
    vector<vector<int>> result;
    vector<int> path;
    void traversal(TreeNode* node, int count){
        if(node->left == nullptr && node->right == nullptr && count == 0){
            result.push_back(path);   //符合条件的路径放入result中
            return;
        }
        if(node->left == nullptr && node->right == nullptr) return;
        if(node->left){
            path.push_back(node->left->val);
            count -= node->left->val;
            traversal(node->left, count);
            count += node->left->val;
            path.pop_back();
        }
        if(node->right){
            path.push_back(node->right->val);
            count -= node->right->val;
            traversal(node->right, count);
            count += node->right->val;
            path.pop_back();
        }
        return;
    }
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        result.clear();
        path.clear();
        if(root == nullptr)return result;
        path.push_back(root->val);
        traversal(root, targetSum-root->val);
        return result;
    }
};

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

class Solution {
public:
    TreeNode* traversal(vector<int>& inorder, vector<int>& postorder){
        //如果后续数字是空的,那么就返回空树
        if(postorder.size() == 0)return NULL;
        //将后序数组的最后一个值作为当前的中间节点
        int rootValue = postorder[postorder.size() - 1];
        TreeNode* root = new TreeNode(rootValue);
        //如果后序数字的大小为1,那么该二叉树就遍历结束
        if(postorder.size() == 1)return root;

        //分割
        //找切割点
        int delimiterIndex;
        for(delimiterIndex = 0; delimiterIndex < inorder.size(); delimiterIndex++){
            //找中间节点在当前中序数组中的位置
            if(inorder[delimiterIndex] == rootValue)break;
        }
        //切割中序数组(左中右),左开右闭
        //中序数组左子树
        vector<int> leftInorder(inorder.begin(), inorder.begin() + delimiterIndex);
        //中序数组右子树
        vector<int> rightInorder(inorder.begin() + delimiterIndex + 1, inorder.end());
        //切割后序数组(左右中),左开右闭
        postorder.resize(postorder.size() - 1);  // 去掉已经使用的中间节点
        vector<int> leftPostorder(postorder.begin(), postorder.begin() + leftInorder.size());
        vector<int> rightPostorder(postorder.begin() + leftInorder.size(), postorder.end());
        //递归
        root->left = traversal(leftInorder, leftPostorder);
        root->right = traversal(rightInorder, rightPostorder);

        return root;
    }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if(inorder.size() == 0 || postorder.size() == 0)return NULL;
        return traversal(inorder, postorder);

    }
};

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

class Solution {
public:
    TreeNode* traversal(vector<int>& preorder, int preorderBegin, int preorderEnd, vector<int>& inorder, int inorderBegin,int inorderEnd){
        if(preorderBegin == preorderEnd)return NULL;
        //将前序数组中的第一个元素当做中间节点
        int rootValue = preorder[preorderBegin]; 
        TreeNode* root = new TreeNode(rootValue);
        if(preorder.size() == 1)return root;
        //在中序数组中,寻找中间节点作为分割点
        int delimiterIndex;
        for(delimiterIndex = inorderBegin; delimiterIndex < inorderEnd; delimiterIndex++){
            if(inorder[delimiterIndex] == rootValue)break;
        }
        //分割中序数组(左闭右开区间)
        int leftInorderBegin = inorderBegin;
        int leftInorderEnd = delimiterIndex;
        int rightInorderBegin = delimiterIndex + 1;
        int rightInorderEnd = inorderEnd;

        //分割前序数组(左闭右开区间)
       preorderBegin = preorderBegin + 1;
       int leftPreorderBegin = preorderBegin;
       int leftPreorderEnd = leftPreorderBegin + delimiterIndex - inorderBegin;
       int rightPreorderBegin = leftPreorderBegin + delimiterIndex - inorderBegin;
       int rightPreorderEnd = preorderEnd; 

       //遍历
       root->left = traversal(preorder, leftPreorderBegin, leftPreorderEnd, inorder, leftInorderBegin, leftInorderEnd);
       root->right = traversal(preorder, rightPreorderBegin, rightPreorderEnd, inorder, rightInorderBegin, rightInorderEnd);

       return root;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if(inorder.size() == 0 || preorder.size() == 0)return NULL;
        //左闭右开原则
        return traversal(preorder, 0, preorder.size(), inorder, 0, inorder.size());
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值