1. 题目: 见左程云老师的《程序员代码面试指南》P22
2. 思路:不得不说,哎作为一个水平低的菜鸟,每一道题都很虐心啊。。。
建立树的原则:(1)每一个数的父节点就是——它左边第一个比它大的数和它右边第一个比她大的数中,较小的一个
(2)如果一个数左边没有比它大的数,右边也没有。就是说,这个数是整个数组的最大值,那么这个数就是Maxtree的节点。
接下来就是首先:如何找到每一个数 左边第一个比它大的值和右边比它大的值 (通过栈来实现,并用两个hash_map分别存储每个元素对应的左边最大值序号和右边最大值序号)
然后,根据建立树的原则进行树的建立
3. 代码实现:
#include<stack>
#include <vector>
#include<iostream>
#include <sstream>
#include <queue>
#include <hash_map>
#include <string>
using namespace std;
class Node
{
public:
Node(int data)
{
this->value = data;
this->left = NULL;
this->right = NULL;
}
public:
int value;
Node *left;
Node *right;
};
void popStackSetMap(stack<int>&stack1, hash_map<int,string>&map1)
{
int temp = stack1.top();
stack1.pop();
stringstream ss;
string str;
if (stack1.empty())
{
map1[temp] = str;
}
else
{
ss << stack1.top();
ss >> str;
map1[temp]=str;
}
}
Node *getMaxTree(vector<int> &arr)
{
Node *root = NULL;
int len = arr.size();
stack<int> stack1;
hash_map<int, string> lBigMap;
hash_map<int, string> rBigMap;
//为数组内的每个数据分别找到一个对应的 左端第一个比他大的值,没有则为空
for (int i = 0; i < len;i++)
{
while (!stack1.empty()&&arr[stack1.top()]<arr[i])
{
popStackSetMap(stack1, lBigMap);
}
stack1.push(i); //注意,这里保存的是数组序号,而不是数组值
}
while (!stack1.empty())
{
popStackSetMap(stack1, lBigMap);
}
//为数组内的每个数据分别找到一个对应的 右端第一个比它大的值,没有则为空
for (int i = len-1; i >=0; i--)
{
while (!stack1.empty() && arr[stack1.top()] < arr[i])
{
popStackSetMap(stack1, rBigMap);
}
stack1.push(i); //注意,这里保存的是数组序号,而不是数组值
}
while (!stack1.empty())
{
popStackSetMap(stack1, rBigMap);
}
//构造Node数组
vector<Node *>nArr;
for (int i = 0; i < len;i++)
{
Node *temp = new Node(arr[i]);
nArr.push_back(temp);
}
//构造树
for (int i = 0; i < len;i++)
{
string ls = lBigMap[i];
string rs = rBigMap[i];
if (ls.empty()&&rs.empty())
{
root = nArr[i];
}
else if (ls.empty())
{
stringstream ss(rs);
int rID;
ss >> rID;
if (nArr[rID]->left==NULL)
nArr[rID]->left = nArr[i];
else
nArr[rID]->right = nArr[i];
}else if (rs.empty())
{
stringstream ss(ls);
int lID;
ss >> lID;
if ( nArr[lID]->left==NULL)
nArr[lID]->left = nArr[i];
else
nArr[lID]->right = nArr[i];
}
else
{
stringstream lss(ls);
int lID;
lss >> lID;
stringstream rss(rs);
int rID;
rss >> rID;
int pID = arr[lID] < arr[rID] ? lID : rID;
if (NULL == nArr[pID]->left)
nArr[pID]->left = nArr[i];
else
nArr[pID]->right = nArr[i];
}
}
return root;
}
void PrintTree(Node *root)
{
queue<Node *> queue1;
Node* last;
Node* nextLast=NULL;
last = root;
if (last != NULL)
{
queue1.push(last);
}
while (!queue1.empty())
{
Node *cur = queue1.front();
printf("%d\t", cur->value);
queue1.pop();
if (cur->left != NULL)
{
queue1.push(cur->left);
nextLast = cur->left;
}
if (cur->right != NULL)
{
queue1.push(cur->right);
nextLast = cur->right;
}
if (cur == last)
{
printf("\n");
last = nextLast;
}
}
}
int main()
{
vector<int> arr = { 3, 4, 5, 1, 2 };
Node *root = NULL;
root = getMaxTree(arr);
PrintTree(root);
system("pause");
return 1;
}