大楼轮廓问题

题意描述

给定一个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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值