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

513.找树左下角的值

层序遍历即可解决。用递归反而不方便。

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

    }
};

112. 路径总和

暴力解法就是遍历树,计算出到每个叶子结点路径的sum,用set存储,看是否有符合target的。

class Solution {
public:
    void getLeafSum(TreeNode* root, unordered_set<int>& sum_set, int sum){
        if(root==nullptr) return;
        
        sum+=root->val;
        if(root->left==nullptr&&root->right==nullptr){
            sum_set.insert(sum);
        }
        getLeafSum(root->left,sum_set,sum);
        getLeafSum(root->right,sum_set,sum);
    }

    bool hasPathSum(TreeNode* root, int targetSum) {
        unordered_set<int> sum_set;
        getLeafSum(root,sum_set,0);
        if(sum_set.find(targetSum)==sum_set.end()) return false;
        else return true;
    }
};

但是我看标答采用了回溯法。这样可以减少多余空间的使用并且减少不必要的查找。

class Solution {
private:
    bool traversal(TreeNode* cur, int count) {
        if (!cur->left && !cur->right && count == 0) return true; // 遇到叶子节点,并且计数为0
        if (!cur->left && !cur->right) return false; // 遇到叶子节点直接返回

        if (cur->left) { // 左
            count -= cur->left->val; // 递归,处理节点;
            if (traversal(cur->left, count)) return true;
            count += cur->left->val; // 回溯,撤销处理结果
        }
        if (cur->right) { // 右
            count -= cur->right->val; // 递归,处理节点;
            if (traversal(cur->right, count)) return true;
            count += cur->right->val; // 回溯,撤销处理结果
        }
        return false;
    }

public:
    bool hasPathSum(TreeNode* root, int sum) {
        if (root == NULL) return false;
        return traversal(root, sum - root->val);
    }
};
  • 找是否有targetval的一个常用小技巧是不累加sum与targetval比较,而是累减看最终结果是否为0,为0则找到了targetval。

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

学数据结构的时候好像手画过这类题,代码咋写还要思考一下。

class Solution {
public:
    TreeNode* traversal(vector<int>& inorder, int ibegin, int iend, vector<int>& postorder, int pbegin, int pend){
        if (ibegin > iend || pbegin > pend) return nullptr;

        TreeNode* root=new TreeNode(postorder[pend]);

        auto it=find(inorder.begin() + ibegin, inorder.begin() + iend + 1,postorder[pend]);
        int midindex=distance(inorder.begin(),it);
        int leftTreeSize=midindex-ibegin;

        root->left=traversal(inorder,ibegin,midindex-1,postorder,pbegin,pbegin+leftTreeSize-1);
        root->right=traversal(inorder,midindex+1,iend,postorder,pbegin+leftTreeSize,pend-1);

        return root;
        
    }

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

用index而不是每一回递归都创建新的左右vector比较优雅。

posted @ 2025-04-12 20:29  ChloeChen0221  阅读(9)  评论(0)    收藏  举报