算法训练营 第十八天

算法训练营 第十八天

day05~

513.找树左下角的值

这道题的难度在于,他需要回传高度和结点值两个信息,一种方法是递归函数的返回值设置为vector<int>,将高度信息和节点值信息保存到数组里,另一种方法是,把高度信息以引用的形式当作形参传入递归函数
方法一:将两个信息作为返回值传递

class Solution {
public:
    
    vector<double> digui(TreeNode* root) {
        if (root == nullptr)
            return { MINNUM,0 };
        if(root->left==nullptr&&root->right==nullptr)
            return { (double)root->val,1 };
        auto leftInfo = digui(root->left);
        auto rightInfo = digui(root->right);
        if (leftInfo[1] >= rightInfo[1])
            return{ leftInfo[0], leftInfo[1] + 1 };
        return {rightInfo[0], rightInfo[1] + 1};
        

    }

    int findBottomLeftValue(TreeNode* root) {
        if(root->left==nullptr&&root->right==nullptr)
            return root->val;
        return digui(root)[0];
        
        
    }
private:
    double MINNUM = -pow(2,31)-1;
};

注:用double的返回值是因为这道题的val范围是-2^31,超过了int的取值范围

方法二:将高度信息作为形参传递

class Solution {
public:
    int maxDepth = INT_MIN;
    int result;
    void traversal(TreeNode* root, int depth) {
        if (root->left == NULL && root->right == NULL) {
            if (depth > maxDepth) {
                maxDepth = depth;
                result = root->val;
            }
            return;
        }
        if (root->left) {
            depth++;
            traversal(root->left, depth);
            depth--; // 回溯
        }
        if (root->right) {
            depth++;
            traversal(root->right, depth);
            depth--; // 回溯
        }
        return;
    }
    int findBottomLeftValue(TreeNode* root) {
        traversal(root, 0);
        return result;
    }
};

112.路径总和

这道题和第257道题很像,就是求二叉树的所有路径,然后判断是否有路径总和和目标和相同的路径。一旦找到路径则不用再进行其他操作了,直接返回true。

class Solution {
public:
    

    bool hasPathSum(TreeNode* root, int targetSum) {
        if (root == nullptr)
            return false;
        pathSum += root->val;
        if (root->left == nullptr && root->right == nullptr && pathSum == targetSum) {
            return true;
        }
        if (root->left) {
            if (hasPathSum(root->left, targetSum))
                return true;
            pathSum -= root->left->val;
        }
        if (root->right) {
            if (hasPathSum(root->right, targetSum)
                return true;
            pathSum -= root->right->val;
        }
        return false;
    }
private:
    int pathSum = 0;
};

113. 路径总和II

这道题和112一样,只不过需要用vector<int>path记录路径

class Solution {
public:


    void hasPathSum(TreeNode* root, int targetSum, vector<int>&  path,vector<vector<int>>& res) {
        if (root == nullptr)
            return ;
        if (root->left == nullptr && root->right == nullptr && 0 == targetSum) {
            res.push_back(path);
            return ;
        }
        if (root->left) {
            path.push_back(root->left->val);
            hasPathSum(root->left, targetSum - root->left->val, path, res);
            path.pop_back();
        }
        if (root->right) {
            path.push_back(root->right->val);
            hasPathSum(root->right, targetSum- root->right->val,path,res);
            path.pop_back();
        }
        return ;
    }
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        vector<vector<int>> res;
        vector<int> path;
        if (root == nullptr)
            return res;
        path.push_back(root->val);
        hasPathSum(root, targetSum-root->val, path, res);
        return res;
    }

};

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

这道题重点是想清楚怎么分割中序和后序序列,以及递归的传入值该怎么传。

class Solution {
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if (postorder.size() == 0)
            return nullptr;
        if (postorder.size() == 1)
            return new TreeNode(postorder[0], nullptr, nullptr);
        TreeNode* root = new TreeNode(postorder.back());
        int index = 0;
        for (; index < inorder.size(); index++) {
            if (inorder[index] == postorder.back())
                break;
        }
        vector<int> leftInorder(inorder.begin(), inorder.begin() + index);
        vector<int> rightInorder(inorder.begin() + index + 1, inorder.end());
        vector<int> leftPostorder(postorder.begin(), postorder.begin() + index);
        vector<int> rightPostorder(postorder.begin() + index, postorder.end() - 1);
        root->left = buildTree(leftInorder, leftPostorder);
        root->right = buildTree(rightInorder, rightPostorder);
        return root;
    }
};

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

这道题的思路和106相同

class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if (preorder.size() == 0)
            return nullptr;
        if (preorder.size() == 1)
            return new TreeNode(preorder[0]);
        
        int index = 0;
        for (; index < inorder.size(); index++) {
            if (inorder[index] == preorder[0])
                break;
        }
        vector<int> leftPreorder(preorder.begin() + 1, preorder.begin() + 1 + index);
        vector<int> rightPreorder(preorder.begin() + 1 + index, preorder.end());
        vector<int> leftInorder(inorder.begin(), inorder.begin() + index);
        vector<int> rightInorder(inorder.begin() + index + 1, inorder.end());
        TreeNode* root = new TreeNode(preorder[0]);
        root->left = buildTree(leftPreorder, leftInorder);
        root->right = buildTree(rightPreorder, rightInorder);
        return root;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值