129. Sum Root to Leaf Numbers

Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number.

An example is the root-to-leaf path 1->2->3 which represents the number 123.

Find the total sum of all root-to-leaf numbers.

For example,

    1
   / \
  2   3
The root-to-leaf path 1->2 represents the number 12.
The root-to-leaf path 1->3 represents the number 13.

Return the sum = 12 + 13 = 25.

方法一:
最笨的方法,可以把所有路径存下来,然后逐一计算。如下:

class Solution {
public:
    int sumNumbers(TreeNode* root) {
        vector<vector<int>> res;
        vector<int> tempres;
        if (root == NULL) return 0;
        helper(root, res, tempres);
        int sum = 0;
        for (int i = 0; i < res.size(); i++) {
            int tempsum = 0;
            int len = res[i].size() - 1;
            double factor = pow(10.0, float(len));
            for (int j = 0; j <= len && factor >= 1; j++) {
                tempsum += res[i][j] * factor;
                factor = factor / 10;
            }
            sum += tempsum;
        }
        return sum;
    }
    void helper(TreeNode* root, vector<vector<int>>& res, vector<int>& tempres) {
        if (root == NULL) return;
        tempres.push_back(root->val);
        if (root->left == NULL && root->right == NULL) {
            res.push_back(tempres);
            tempres.pop_back();
            return;
        }
        if (root->left) {
            helper(root->left, res, tempres);
        }
        if (root->right) {
            helper(root->right, res, tempres);
        }
        tempres.pop_back();
        return;
    }
};

这里一开始,leetcode的测试用例最后一例显示答案错误。因为在当路径过长的时候,factor可能会越界,一开始用int就越界了,后来改用double就好了。

方法二: 简洁递归
其实从root到leaf, 每次都用现有的和乘以10加上新访问的节点值就可以了。
所以其实可以递归的很简洁:

class Solution {
public:
    int sumNumbers(TreeNode* root) {
        return helper(root, 0);
    }

    int helper(TreeNode* root, int prevSum) {
        if (root == NULL) return 0;
        prevSum = prevSum * 10 + root->val;
        if (root->left == NULL && root->right == NULL) return prevSum;
        else return helper(root->left, prevSum) + helper(root->right, prevSum);
    }
};

方法三:
in-place 操作,non-recursive。可以把previous sum存在每一个节点中。这样就可以很方便的往下传递。

class Solution {
public:
    int sumNumbers(TreeNode* root) {
        if (root == NULL) return 0;
        int sum = 0;
        stack<TreeNode*> mystack;
        mystack.push(root);
        while (!mystack.empty()) {
            TreeNode* curr = mystack.top();
            mystack.pop();
            if (curr->left == NULL && curr->right == NULL) {
                sum += curr->val;
            }
            if (curr->left) {
                curr->left->val += curr->val * 10;
                mystack.push(curr->left);
            }
            if (curr->right) {
                curr->right->val += curr->val * 10;
                mystack.push(curr->right);
            }
        }
        return sum;
    }
};

方法四: 不改变原始数据的情况下non-recursive,只能用两个stack了。一个stack存储访问的节点,一个stack存储这个节点之前的sum.

class Solution {
public:
    int sumNumbers(TreeNode* root) {
        if (root == NULL) return 0;
        int sum = 0;
        stack<TreeNode*> mystack;
        stack<int> prevSum;
        mystack.push(root);
        prevSum.push(0);
        while (!mystack.empty()) {
            TreeNode* curr = mystack.top();
            int psum = prevSum.top();
            mystack.pop();
            prevSum.pop();
            psum = psum * 10 + curr->val;
            if (curr->left == NULL && curr->right == NULL) {
                sum += psum;
            }
            if (curr->left) {
                mystack.push(curr->left);
                prevSum.push(psum);
            }
            if (curr->right) {
                mystack.push(curr->right);
                prevSum.push(psum);
            }
        }
        return sum;
    }
};

其实这题也可以用queue来做广度优先的讨论,无所谓,只要最后在找到每一个leaf的时候将正确的路径和加到总的sum里就行。不管是stack还是queue,只要同步push和pop之前的prevSum 和节点即可。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值