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.

(1)递归的解法:
运行时间超长的代码:有点类似于112,113的path sum,112,113,均是求从根节点到叶子节点的节点元素之和等于某一具体的值得路径,112是判断存不存在这样一条路径,113是判断存不存在这样的路径,并返回出满足条件的多条路径,均采用的是前序遍历的思想,因为前序遍历是优先遍历根节点的,其次是左孩子,再是右孩子。

void sumNumbers(TreeNode* root,int &sum,int temp)
    {
        temp = temp*10+root->val;
        if(root->left == NULL && root->right == NULL)
            sum+=temp;
        if(root->left!=NULL)
            sumNumbers(root->left,sum,temp);

        if(root->right!=NULL)
            sumNumbers(root->right,sum,temp); 
    }
    int sumNumbers(TreeNode* root) {
        if(root == NULL) return 0;
        else if(root->left == NULL && root->right == NULL) return root->val;

        int sum = 0;
        int temp = 0;
        sumNumbers(root,sum,temp);
      }

在上述代码之后,精华上述代码后,代码如下(运行时间依旧没有提高上去):

int sumNumbers(TreeNode* root,int sum)
    {
        if(root == NULL) return 0;
        sum = sum*10+root->val;
        if(root->left == NULL && root->right == NULL)
            return sum;

        return  sumNumbers(root->left,sum)+sumNumbers(root->right,sum); 
    }
    int sumNumbers(TreeNode* root) {
        return sumNumbers(root,0);
    }

同样的逻辑思路,发现用java实现能节约时间,将运行时间由3ms提升至1ms

public int sumNumbers(TreeNode root) {
        if (root == null)
            return 0;
        return sumR(root, 0);
    }
    public int sumR(TreeNode root, int x) {
        if (root.right == null && root.left == null)
            return 10 * x + root.val;
        int val = 0;
        if (root.left != null)
            val += sumR(root.left, 10 * x + root.val);
        if (root.right != null)
            val += sumR(root.right, 10 * x + root.val);
        return val;
    }

同样将上述思路扩展到链表上,如果把这个问题扩展一下,在链表中,也有类似问题。如果一个链表是1->2->3->4->5,那么它将表达12345这个数,完美~~

int sumLinkedList(ListNode* node, int sum){  
    if(node==NULL)  
        return sum;  
    sum=sum*10+node->val;  
    return sumLinkedList(node->next,sum);  
}  

int sumLinkedList(ListNode* root){  
    return sumLinkedList(root,0);  
}  

(2)非递归的方法
代码一:–运行时间比递归的时间还要长,性能要差,非递归的方法注意一次循环只能压入一个节点,因为防止压入多次造成cur = (cur - temp->val) / 10的计算错乱

int sumNumbers(TreeNode* root) {
        if(root == NULL)
            return 0;

        stack<TreeNode*> sta;
        sta.push(root);
        map<TreeNode*, bool> visited;
        visited[root] = true;
        int result = 0;
        int cur = 0;
        cur += root->val;
        while(!sta.empty())
        {
            TreeNode* temp = sta.top();
            if(temp->left != NULL && visited[temp->left] == false)
            {
                sta.push(temp->left);
                visited[temp->left] = true;
                cur = cur * 10 + temp->left->val;
                continue; //一次只能压入一个节点,否则压入多次cur = (cur - temp->val) / 10的计算会错乱
            }

            if(temp->right != NULL && visited[temp->right] == false)
            {
                sta.push(temp->right);
                visited[temp->right] = true;
                cur = cur * 10 + temp->right->val;
                continue;
            }

            if(temp->left == NULL && temp->right == NULL)
                result += cur;

            sta.pop();
            cur = (cur - temp->val) / 10;
        }
        return result;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值