代码随想录 - 训练营8期- day 18

● 513.找树左下角的值
● 112. 路径总和 113.路径总和ii
● 106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树

513. 找树左下角的值

先迭代法水一下

class Solution {
public:
    int findBottomLeftValue(TreeNode* root) {
        queue<TreeNode*> q;
        q.push(root);
        int res = 0;
        while(!q.empty()) {
            int size = q.size();
            for(int i = 0; i < size; ++i) {
                TreeNode* node = q.front();
                q.pop();
                if(!i) res = node->val;
                if(node->left != nullptr) q.push(node->left);
                if(node->right != nullptr) q.push(node->right);
            }
        }
        return res;
    }
};

递归的话……应该还是得DFS

一遍过,很容易

递归主要是还是判断边界条件,叶子结点自然是 【左右孩子为 nullptr】

然后还要最大深度

先搜索左边且depth > maxDepth 保证了永远都是最左边那个子结点才判断,正好符合题意

class Solution {
    int maxDepth{};
    int res{};
    void DFS(TreeNode* node, int depth) {
        if(node->left == nullptr && node->right == nullptr) {
            if(depth > maxDepth) {
                res = node->val;
                maxDepth = depth;
            }
            return;
        }

        if(node->left != nullptr) {
            depth++;
            DFS(node->left, depth);
            depth--;
        }
        if(node->right != nullptr) {
            depth++;
            DFS(node->right, depth);
            depth--;
        }
    }
public:
    int findBottomLeftValue(TreeNode* root) {
        DFS(root, 1);
        return res;
    }
};

112. 路径总和

看题目都知道是回溯

class Solution {
    bool hasPath {};
    void DFS(TreeNode* node, int target, int sum) {
        if(node->left == nullptr && node->right == nullptr) {
            if(sum == target) {
                hasPath = true;
            }
            return;
        }

        if(node->left != nullptr) {
            sum += node->left->val;
            DFS(node->left, target, sum);
            sum -= node->left->val;
        }
        if(node->right != nullptr) {
            sum += node->right->val;
            DFS(node->right, target, sum);
            sum -= node->right->val;
        }
    }
public:
    bool hasPathSum(TreeNode* root, int targetSum) {
        if(root == nullptr) return false;
        DFS(root, targetSum, root->val);
        return hasPath;
    }
};

113. 路径总和II

上一题的改改就行

class Solution {
    vector<vector<int>> res;
    void DFS(TreeNode* node, int target, int sum, vector<int>& path) {
        if(node->left == nullptr && node->right == nullptr) {
            if(sum == target) {
                res.push_back(path);
            }
            return;
        }

        if(node->left != nullptr) {
            sum += node->left->val;
            path.push_back(node->left->val);
            DFS(node->left, target, sum, path);
            sum -= node->left->val;
            path.pop_back();
        }
        if(node->right != nullptr) {
            sum += node->right->val;
            path.push_back(node->right->val);
            DFS(node->right, target, sum, path);
            sum -= node->right->val;
            path.pop_back();
        }
    }
public:
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        if(root == nullptr) return {};

        vector<int> path{root->val};
        DFS(root, targetSum, root->val, path);
        return res;
    }
};

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

这种题型只学过理论,还真没写过码

依稀记得当年没有搞熟练结果考试时候卡了好久...

首先,后序遍历最后一个是根节点,这个都懂

然后直接看随想录...真忘却了

看了下随想录大概懂了(原来当年好像确实没学会这个,只是以为自己会了 抽象)

注意就是切割数组时候

中序数组可以按照元素索引切割,后序数组则是按照中序数组的大小。

优化的话,就是不用构造vector,只传一次引用,然后传索引。

class Solution {
    TreeNode* Traversal(vector<int>& inorder, vector<int>& postorder) {
        if(postorder.size() == 0) return nullptr;
        TreeNode* root = new TreeNode(postorder.back());

        int idx = 0;
        for(; idx < inorder.size(); ++idx) {
            if(inorder[idx] == root->val) {
                break;
            }
        }

        vector<int> lInorder( inorder.begin(), inorder.begin() + idx );
        vector<int> rInorder( inorder.begin() + idx + 1, inorder.end() );

        vector<int> lPostorder( postorder.begin(), postorder.begin() + lInorder.size() );
        vector<int> rPostorder( postorder.begin() + lInorder.size(), postorder.end() - 1 );

        root->left = Traversal(lInorder, lPostorder);
        root->right = Traversal(rInorder, rPostorder);

        return root;
    }

public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        return Traversal(inorder, postorder);
    }
};

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

基本上是一样

class Solution {
    TreeNode* Tarversal(vector<int>& preorder, vector<int>& inorder) {
        if(!preorder.size() || !inorder.size()) return nullptr;
        TreeNode* root = new TreeNode(preorder[0]);

        int idx = 0;
        for(; idx < inorder.size(); ++idx) {
            if(inorder[idx] == root->val) {
                break;
            }
        }

        vector<int> lInorder(inorder.begin(), inorder.begin() + idx + 1);
        vector<int> rInorder(inorder.begin() + idx + 1, inorder.end() );

        vector<int> lPreorder(preorder.begin() + 1, preorder.begin() + 1 + idx);
        vector<int> rPreorder(preorder.begin() + 1 + idx, preorder.end());

        root->left = Tarversal(lPreorder, lInorder);
        root->right = Tarversal(rPreorder, rInorder);
        return root;
    }
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        return Tarversal(preorder, inorder);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值