代码改变世界

leet code 1302. 层数最深叶子节点的和

2020-06-01 00:13  woshihuangrulin  阅读(159)  评论(0编辑  收藏  举报

先看题目:

给你一棵二叉树,请你返回层数最深的叶子节点的和。
示例:
输入:root = [1,2,3,4,5,null,6,7,null,null,null,null,8] 输出:15   提示: 树中节点数目在 1 到 10^4 之间。 每个节点的值在 1 到 100 之间。

看到题目一定要审题啊! 审题啊! 审题啊!,重要的事情说三遍,代码写完了突然发现结果怎么不对,哎,都是泪,题目要求很简单,找到最深的叶子节点的值的,首先输入是一个二叉树,我首先想到的是用递归来遍历,找到最深的叶子结点,但是我们怎么存储某一深度的叶子结点的和呢,毕竟在没有遍历完前我们还不知道它是不是最深的,我首先想到的是定义一个unordered_map来存储每一个深度的叶子结点的和,还有一种方法就是只存储最深的叶子结点对应的值得和,如果找到更深的就更新,如果找到相等的就加到这个值上,貌似我的定义map的方法更消耗内存了,这个优化很简单,上我的代码:

class Solution {
public:
    int deepestLeavesSum(TreeNode* root) {
        if (root == NULL) {
            return 0;
        }
        int max_depth = 0;
        int cur_depth = 0;
        unordered_map<int, int> depth_sum_map; // 层数,相同层数的叶子结点的和

        searchEndNode(root, cur_depth, max_depth, depth_sum_map);

        auto itr = depth_sum_map.find(max_depth);

        if (itr == depth_sum_map.end()) {
            return -1;
        }
        return itr->second;
    }

    void searchEndNode(TreeNode* root, int cur_depth, int& max_depth, unordered_map<int, int>& depth_sum_map) {
        cur_depth++; // 别的不管 把这一层层数加上

        if (root->left == NULL && root->right == NULL) { // 判断是叶子结点
            if (cur_depth > max_depth) {  //如果比最大深度大,更新最大深度
                max_depth = cur_depth;
            }
            auto itr = depth_sum_map.find(cur_depth);
            if (itr == depth_sum_map.end()) { //查找是否已经有此深度的节点,如果没有,插入此深度和其对应的叶子结点值
                // depth_sum_map[cur_depth] = root->val;
                depth_sum_map.insert(pair<int, int>{cur_depth, root->val});
            }
            else {
                itr->second+=root->val;  // 如果已经有了,增加此结点的值
            }
            return;
        }

        if (root->left != NULL) { // 左子节点存在
            searchEndNode(root->left, cur_depth, max_depth, depth_sum_map);
        }
        if (root->right != NULL) { // 右子节点存在
            searchEndNode(root->right, cur_depth, max_depth, depth_sum_map);
        }
            
        return;
    }
};

多说一句,细节决定成败,这个代码我写了一个小时,总结下来就是理解题目错误耗时20分钟,遍历代码不熟悉导致耗时20分钟(这里要讲一下就是二叉树迭代结束条件是找到了叶子结点,即没有左右子节点,多写几次就熟悉了),最后答案老是不对,找bug耗时20分钟,最后发现是一个赋值等号写成了判断相等的符号,细节决定成败!!!!!!!!

稍微优化了下代码,不存储那么多和了:

class Solution {
public:
    int deepestLeavesSum(TreeNode* root) {
        if (root == NULL) {
            return 0;
        }
        int max_depth = 0;
        int cur_depth = 0;
        // unordered_map<int, int> depth_sum_map; // 层数,相同层数的叶子结点的和
        int max_sum = 0;

        searchEndNode(root, cur_depth, max_depth, max_sum);
        return max_sum;
    }

    void searchEndNode(TreeNode* root, int cur_depth, int& max_depth, int& max_sum) {
        cur_depth++;

        if (root->left == NULL && root->right == NULL) { // 如果是叶子结点
            if (cur_depth > max_depth) {  //如果比最大深度大,更新最大深度
                max_depth = cur_depth;
                max_sum = root->val;
            }
            else if (cur_depth == max_depth) {
                max_sum += root->val;
            }
           
            return;
        }

        if (root->left != NULL) {
            searchEndNode(root->left, cur_depth, max_depth, max_sum);
        }
        if (root->right != NULL) {
            searchEndNode(root->right, cur_depth, max_depth, max_sum);
        }
            
        return;
    }
};