BinaryPathSum

这道题目思路是瞿神提出的,瞿神能力确实很强,大一下,没有OI经历,算法已经非常出色了,小弟确实佩服,想当年小弟还在纠结于高数C++。。。
可见瞿神确实是付出了超出常人几倍甚至几十倍的时间,算法数据结构似乎很多方面比我还强。。。。

这道题目是Leetcode一道挺难的题目,找BT里面最长的path,任意两个点的,C(n,2)里面找,一个DP,后序顺序推进,保证孩子都计算出了,我的代码有点冗长,但是最后还是TLE了,具体原因不明,
后来发现没有记忆花存储,递归了,改了还是TLE。

// LeetCodeLast50.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <map>
#include <stack>
#include <queue>
using namespace std;



class Solution {
    struct TreeNode {
      int val;
      TreeNode *left;
      TreeNode *right;
      TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  };

public:
    TreeNode* root;
    int dp[10000];
    map<TreeNode*, int> nodemap;

    int maxPathSum(TreeNode *root) {
        if(root==NULL) return 0;
        LevelOrder(root);
        stack<TreeNode* > S;
        S.push(root);
        TreeNode* p,*pre=NULL;
        while(!S.empty())
        {
            p=S.top();
            if( (p->left==NULL && p->right==NULL) || (pre!=NULL &&(pre==p->left || pre==p->right)))
            {
                d(p);

                S.pop();
                pre=p;
            }
            else
            {
                if(p->right)
                    S.push(p->right);
                if(p->left)
                    S.push(p->left);
            }
        }
        map<TreeNode*, int> ::iterator it=nodemap.begin();
        int max=-1000;
        /*
        if(dp[it->second]==dp[nodemap[it->first->left]]+it->first->val)
            max=dp[it->second]+dp[nodemap[it->first->right]];
        if(dp[it->second]==dp[nodemap[it->first->right]]+it->first->val)
        {
            if(max<dp[it->second]+dp[nodemap[it->first->left]])
                max=dp[it->second]+dp[nodemap[it->first->left]];
        }*/

        for(;it!=nodemap.end();it++)
        {
            /*
            if(it->first->left!=NULL && dp[it->second]==dp[nodemap[it->first->left]]+it->first->val)
            {
                if(it->first->right!=NULL &&max<dp[it->second]+dp[nodemap[it->first->right]])
                    max=dp[it->second]+dp[nodemap[it->first->right]];
                else if(it->first->right==NULL)
                {
                    if(max<dp[it->second])
                        max=dp[it->second];
                }
            }
            if(it->first->right!=NULL && dp[it->second]==dp[nodemap[it->first->right]]+it->first->val)
            {
                if(it->first->left!=NULL &&max<dp[it->second]+dp[nodemap[it->first->left]])
                    max=dp[it->second]+dp[nodemap[it->first->left]];
                else if(it->first->left==NULL)
                {
                    if(max<dp[it->second])
                        max=dp[it->second];
                }
            }
            if(it->first->left==NULL && it->first->right==NULL)
            {
                if(max<dp[it->second])
                    max=dp[it->second];
            }
            else if(it->first->left!=NULL && it->first->right==NULL)
            {
                if(max<dp[it->second])
                    max=dp[it->second];
            }
            else if(it->first->left==NULL && it->first->right!=NULL)
            {
                if(max<dp[it->second])
                    max=dp[it->second];
            }*/

            if(it->first->left!=NULL && it->first->right!=NULL)
            {
                if(dp[it->second]==dp[nodemap[it->first->left]]+it->first->val && max<dp[it->second]+dp[nodemap[it->first->right]])
                    max=dp[it->second]+dp[nodemap[it->first->right]];
                else if(dp[it->second]==dp[nodemap[it->first->right]]+it->first->val && max<dp[it->second]+dp[nodemap[it->first->left]])
                    max=dp[it->second]+dp[nodemap[it->first->left]];
                else
                {
                    if(max<dp[it->second])
                        max=dp[it->second];
                }
            }
            else
            {
                if(max<dp[it->second])
                    max=dp[it->second];
            }
        }
        return max;
    }
    void LevelOrder(TreeNode* root)
    {
        queue<TreeNode* > Q;
        Q.push(root);
        int i=0;
        while(!Q.empty())
        {
            TreeNode* p=Q.front();
            nodemap[p]=i;
            i++;
            Q.pop();
            if(p->left!=NULL)
                Q.push(p->left);
            if(p->right!=NULL)
                Q.push(p->right);
        }

        memset(dp,0,sizeof(int)*i);
    }
    int d(TreeNode*p)
    {
        //if(!node[i])return dp[i]=0;
        //int l=node[i].l,r=node[i].r;
        int x;
        if((x=dp[nodemap[p]])!=0) return x;
        int lefti,righti,i=nodemap[p];

        if(p->left) 
        {    
            lefti=nodemap[p->left];
            dp[lefti]=d(p->left);
        }
        if(p->right)
        {
            righti=nodemap[p->right];
            dp[righti]=d(p->right);
        }

        //if(node[l])dp[l]=d(l);
        //if(node[r])dp[r]=d(r);

        if(p->left && p->right)
            return dp[i]=max(max(dp[lefti],dp[righti]),0)+p->val;
        else if(p->left && p->right==NULL)
            return dp[i]=max(dp[lefti],0)+p->val;
        else if(p->left==NULL && p->right)
            return dp[i]=max(dp[righti],0)+p->val;
        else 
            return dp[i]=p->val;
    }
    int Max(int a, int b, int c, int d)
    {
        int max=a;
        if(max<b) max=b;
        if(max<c) max=c;
        if(max<d) max=d;
        return max;
    }

    void Create(TreeNode* & root)
    {
        int data;
        cin>>data;
        if(data == -1) root=NULL;
        else
        {
            root=new TreeNode(data);
            Create(root->left);
            Create(root->right);
        }
    }

    void CreateLevelOrder(TreeNode* &root)
    {
        queue<TreeNode*> Q;
        int data;
        cin>>data;
        if(data==-1) 
        {
            root=NULL;
            return;
        }
        else 
            root=new TreeNode(data);
        Q.push(root);
        while(!Q.empty())
        {
            TreeNode* p=Q.front();
            Q.pop();
            cin>>data;
            if(data==-1)
                p->left=NULL;
            else
                p->left=new TreeNode(data),Q.push(p->left);
            cin>>data;
            if(data==-1)
                p->right=NULL;
            else
                p->right=new TreeNode(data),Q.push(p->right);
        }
    }

};

int _tmain(int argc, _TCHAR* argv[])
{
    freopen("in.txt","r",stdin);
    Solution S;

    S.Create(S.root);
    cout<<endl<<S.maxPathSum(S.root)<<endl;
    return 0;
}

后来还是改成了记忆化搜索,用瞿神的代码基础上,修改成leetcode的接口AC了

#include <unordered_map>
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

class Solution
{


public:
    unordered_map<TreeNode*, int> nodemap;
    TreeNode *root;
    int ans=-0x3ffffff,cnt=0;
    Solution():root(NULL)
    {
    }
    int Create(TreeNode*& root)
    {
        int data,x;
        cin>>data;
        if(data == -1){
            root=NULL;
            return 0;
        }
        else
        {
            if(root!=NULL)
                root->val=data;
            else
                root=new TreeNode(data);
            //root->left=new TreeNode(0);
            //root->right=new TreeNode(0);
            Create(root->left);
            Create(root->right);
            //x=max(0,max(Create(root->left),Create(root->right)))+root->val;
            //nodemap[root]=x;
        }
    }
    int PreOrder(TreeNode* root)
    {

        if(root)
        {
            //cout<<root->val<<" ";
            if(nodemap.find(root)!=nodemap.end()) return nodemap[root]; 
            int x;
            x=max(0,max(PreOrder(root->left),PreOrder(root->right)))+root->val;
            nodemap[root]=x;
            return x;
        }
        else
            return 0;

    }
    int get_max(TreeNode *x)
    {
        if(!x)return 0;
        int tmp=nodemap[x];
        if(x->left&&x->right)
        {
            if(tmp==nodemap[x->left]+x->val&&nodemap[x->right]>0)return tmp+nodemap[x->right];
            if(tmp==nodemap[x->right]+x->val&&nodemap[x->left]>0)return tmp+nodemap[x->left];
        }
        return tmp;
    }
    int maxPathSum(TreeNode *x)
    {
        if(!cnt)PreOrder(x),cnt++;
        if(!x)return 0;
        if(x->left)ans=max(ans,maxPathSum(x->left));
        if(x->right)ans=max(ans,maxPathSum(x->right));
        ans=max(ans,get_max(x));
        return ans;
    }
};

Posted by richard爱闹 - 8月 10 2014
如需转载,请注明: 本文来自 Richard