构造Maxtree

来源:互联网 发布:java 效率最高的排序 编辑:程序博客网 时间:2024/05/13 17:05

题目描述

先给你一个数组,每个元素都不重复出现,让你构造一课二叉树,这个二叉树满足,父节点值比子节点值大。要求时间复杂度O(N) 空间复杂度 O(N)

分析

  它虽然很像堆,但堆的时间复杂度构造的是nlog2n,所以不行。
  我们方法是这样的,遍历这个数组,找到每一个数左边第一个最大的和右边第一个最大的,选择它们俩个中较小的那个数。如果左边或右边没有,那么就选择有的那个,如果都没有则这个数肯定是最大的数。
  选择出来的数,我们把它当做该数的父节点。以这样的方式构造该树。

证明

  上面这个方法,必定每个数字往上一直上溯,肯定能找到一个最大值。所以它满足只构造出来了一棵树。
  那么这棵树为什么是二叉树呢?试想下,如果pCur的左子树有2个子节点,记为L1、L2。那么肯定有如下规则,pCur的值大于L1和L2。L1/L2值首先不是同一个值,它们之间有大小关系之分。其次根据我们的规则,我们只选择第一个比它大的数在左边/右边,并且最后在左边/右边中选一个较小的当做其父节点。所以必定可以推出L1与L2父节点不可能同时为PCur。
  证明完毕,通过上面方法,可以构造出一个二叉树并满足要求

变形

  那么现在我们变下,生成Mintree,怎么办呢?
  很简单,找最边第一个比它小的和右边第一个比它小的,步骤如上,俩个都有很简单,选较大那个。因为选较大那个不会生成歧义。

代码

struct Node{    Node(int data)    :_data(data), _pLeft(nullptr), _pRight(nullptr)    {}    bool operator>(Node&object)    {        return _data > object._data;    }    int _data;    Node*_pLeft;    Node*_pRight;};Node * GetMaxTree(vector<int>&v){    vector<Node> Ncon;    for (auto&i : v)    {        Ncon.push_back(Node(i));    }    stack<Node*> scon;    unordered_map<Node*, Node*> unoLcon;    unordered_map<Node*, Node*> unoRcon;    for (auto&i : Ncon)    {        while (!scon.empty() && scon.top()->_data < i._data)        {                Node*child = scon.top();                scon.pop();                if (!scon.empty())                {                    unoLcon.insert(make_pair(child, scon.top()));                }                else                {                    unoLcon.insert(make_pair(child, nullptr));                }        }        scon.push(&i);    }    while (!scon.empty())    {        Node*child = scon.top();        scon.pop();        if (!scon.empty())        {            unoLcon.insert(make_pair(child, scon.top()));        }        else        {            unoLcon.insert(make_pair(child, nullptr));        }    }    for (int k=Ncon.size()-1;k>=0;--k)    {        Node &i = Ncon[k];        while (!scon.empty() && scon.top()->_data < i._data)        {                Node*child = scon.top();                scon.pop();                if (!scon.empty())                {                    unoRcon.insert(make_pair(child, scon.top()));                }                else                {                    unoRcon.insert(make_pair(child, nullptr));                }        }        scon.push(&i);    }    while (!scon.empty())    {        Node*child = scon.top();        scon.pop();        if (!scon.empty())        {            unoRcon.insert(make_pair(child, scon.top()));        }        else        {            unoRcon.insert(make_pair(child, nullptr));        }    }    Node  * head = nullptr;    for (auto&i : Ncon)    {        Node*pleft = unoLcon[&i];        Node*pRight = unoRcon[&i];        if (pleft == nullptr&&pRight==nullptr)        {            head = &i;        }        else if (pleft == nullptr)        {            if (pRight->_pLeft == nullptr)            {                pRight->_pLeft = &i;            }            else            {                pRight->_pRight = &i;            }        }        else if (pRight == nullptr)        {            if (pleft->_pLeft == nullptr)            {                pleft->_pLeft = &i;            }            else            {                pleft->_pRight= &i;            }        }        else        {            Node *parent = (pleft->_data > pRight->_data) ? pRight : pleft;            if (parent->_pLeft == nullptr)            {                parent->_pLeft = &i;            }            else            {                parent->_pRight = &i;            }        }    }    return head;}