【第十八天】状态渐渐找回

今天的感悟:遇到一般二叉树题,如果没有思路,应该先考虑求高度还是求深度!

1.Find Bottom Left Tree Value

这道题如果用iteration(层序遍历)就太trivial了,故略。如果用递归,应该首先判断是不是处在最大深度。如果是,从中选择最左边的即可。
怎么从中选择最左边的呢?设global variable MAX,这样,当最左边的一旦被找到,无论right branch在递归的哪一层,就能立马知道找到了,从而让后续查找失败。

class Solution {
private:
    int val;
    int MAX;
    int findmaxDepth(TreeNode* root){ //2
        if(!root) return 0;
        int lmax = 1 + findmaxDepth(root->left);
        int rmax = 1 + findmaxDepth(root->right);
        return max(lmax, rmax);
    }

    void findValue(TreeNode* root, int cur){
        if(!root) return;

        if(cur == MAX){
            val = root->val;
            MAX = -1;
            return;
        }
        if(root->left){
            findValue(root->left, cur+1);
        }
        if(root->right){
            findValue(root->right, cur+1);
        }
    }

public:
    int findBottomLeftValue(TreeNode* root) {
        MAX = findmaxDepth(root);
        val = root->val;
        findValue(root, 1);
        return val;
    }
};

2.Path Sum

这破题还真挺难,做了挺久,交了挺多次的。主要是trivial case太多了,不好搞。

class Solution {
private:
    bool res = false;
    bool process = false;
    void backtracking(TreeNode* root, int target, int sum){
        if(!root->left && !root->right) {sum += root->val; process = true;}
        if(sum == target && process && !root->left && !root->right) {
            res = true; 
            return;
        }

        if(root->left){
            process = true;
            backtracking(root->left, target, sum + root->val);
        }

        if(root->right){
            process = true;
            backtracking(root->right, target, sum + root->val);
        }

        return;
    }
public:
    bool hasPathSum(TreeNode* root, int targetSum) {
        if(!root) return false;
        backtracking(root, targetSum, 0);
        return res;
    }
};

…刚刚看了看答案,发现自己就是大笨比。居然会有这么简洁的解决方案…太厉害了

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

3.Path Sum II

这才是理想的。就是回溯,但是把循环过程写出来了而已。

class Solution {
private:
    vector<vector<int>> res;
    vector<int> tmp;
    void backtracking(TreeNode* root, int sum){
        if(!root) return;
        // if(sum < root->val) return; 这行不能加,因为有负数情况,手欠了。
        if(!root->left && !root->right && sum == root->val){
            tmp.push_back(root->val);
            res.push_back(tmp); 
            tmp.pop_back();
            return;
        }

        if(root->left){
            tmp.push_back(root->val);
            backtracking(root->left, sum-root->val);
            tmp.pop_back();
        }

        if(root->right){
            tmp.push_back(root->val);
            backtracking(root->right, sum-root->val);
            tmp.pop_back();
        }
        return;
    }
public:
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        backtracking(root, targetSum);
        return res;
    }
};

4.Construct Binary Tree from Inorder and Postorder Traversal

我的想法是对的,但最后没写对,于是照着答案小改了一下,就过了。分三步:

  1. 找post-order最后一个元素(就是root)
  2. 在in-order里找这个元素
  3. 对应在post-order里,左边就是这个root的left branch,右边(包含这个)就是right branch.
class Solution {
private:
    int find(vector<int> vec, int target){
        for(int i = 0; i < vec.size(); ++i){
            if(vec[i] == target) return i;
        }
        return -1;
    }

public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if(inorder.size() == 0) return nullptr;
        TreeNode* root = new TreeNode(postorder[postorder.size()-1]);
        int div = find(inorder, root->val);

        vector<int> v1(inorder.begin(), inorder.begin() + div);
        vector<int> v3(inorder.begin()+div+1, inorder.end());
        postorder.resize(postorder.size()-1);
        vector<int> v2(postorder.begin(), postorder.begin() + v1.size());
        vector<int> v4(postorder.begin()+v1.size(), postorder.end());

        root->left = buildTree(v1, v2);
        root->right = buildTree(v3, v4);
        return root;
    }
};

剩下前序和中序构造树的题找时间再做吧,估计思路是相近的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值