题意描述
给定一个N行3列的二维数组,每一行表示有一座大楼,一共有N座大楼,所有大楼的地步都坐落在X轴上,每一行的三个值(a,b,c)代表每座大楼从(a,0)开始,到(b,0)点结束,高度为c,输入的数据可以保证a<b,且a,b,c均为正数,大楼之间可以重合,请输入整体轮廓线。
例子:给定一个二维数组{{1,3,3},{2,4,4},{5,6,1}}
输出轮廓线为{{1,2,3},{2,4,4},{5,6,1}}
思路描述
1) 首先我们对数据进行处理,例如将[1,3,3]处理为(1,3,上)(3,3,下)
2) 然后对处理得到的所有信息按照位置排序
3) 遍历得到的数据,如果向上,那么看看在高度map是否有这条数据,如果有就让其出现次数加加,如果没有出现过,就插入一条数据。如果向下,那么看看在高度map中的数据出现次数是否为1,如果是1,那么就直接溢出掉该条数据,如果不为1,就将出现次数减减。在遍历的过程中得到每个位置后的高度记录在另外一张map中
4) 根据第三步得到的map构建轮廓线
示例代码
class Info
{
public:
Info()
:m_pos(0)
, m_height(0)
, m_direction(false)
{
}
Info(int pos, int height, bool direction)
:m_pos(pos)
, m_height(height)
, m_direction(direction)
{
}
int m_pos;
int m_height;
bool m_direction;
};
class Comparetor
{
public:
bool operator()( Info info1, Info info2)
{
if (info1.m_pos != info2.m_pos)
{
return info1.m_pos < info2.m_pos;
}
if (info1.m_direction != info2.m_direction)
{
return info1.m_direction ? true-1 : false;
}
return 0;
}
};
vector<vector<int>> buildingOutline(vector<vector<int>> &outline)
{
vector<Info> info;
for (int i = 0; i < outline.size(); i++)
{
info.push_back(Info(outline[i][0], outline[i][2], true));
info.push_back(Info(outline[i][1], outline[i][2], false));
}
std::sort(info.begin(), info.end(), Comparetor());
map<int, int> htMap;
map<int, int> pmMap;
for (int i = 0; i < info.size(); i++)
{
if (info[i].m_direction)
{
if (htMap.find(info[i].m_height) != htMap.cend())
{
htMap[info[i].m_height]++;
}
else
{
htMap.insert({info[i].m_height, 1});
}
}
else
{
if (htMap[info[i].m_height] == 1)
{
htMap.erase(info[i].m_height);
}
else
{
htMap[info[i].m_height]--;
}
}
if (htMap.empty())
{
pmMap.insert({ info[i].m_pos, 0 });
}
else
{
pmMap.insert({ info[i].m_pos, htMap.rbegin()->first });
}
}
vector<vector<int>> res;
int start = 0;
int height = 0;
for (auto e : pmMap)
{
int curPosition = e.first;
int curMaxHeight = e.second;
if (height != curMaxHeight)
{
if (height != 0)
{
vector<int> temp;
temp.push_back(start);
temp.push_back(curPosition);
temp.push_back(height);
res.push_back(temp);
}
start = curPosition;
height = curMaxHeight;
}
}
return res;
}