218. The Skyline Problem

天际线轮廓
input: [ [2 9 10], [3 7 15], [5 12 12], [15 20 10], [19 24 8] ]
output: [2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0]

// 高楼的信息
var arr = new int[][]
{
   new int[] { 2, 9, 10 },
   new int[] { 3, 7, 15 },
   new int[] { 5, 12, 12 },
   new int[] { 15, 20, 10 },
   new int[] { 19, 24, 8 },
};
var rslt = GetSkyLine(arr);
foreach (var item in rslt)
{
	Console.WriteLine($"{item.Key} {item.Value}");
}

public Dictionary<int, int> GetSkyLine(int[][] buildings)
{
	Dictionary<int, int> rslt =new Dictionary<int, int>();
	var tree = new SegmentTree();
	int lastHeight = 0;
	bool isCheck = false;
	var item = Discretization(buildings);
	var posMap = item.Item1;
	var pos = item.Item2;
	int[] tmp = new int[posMap.Count];

	tree.Init(tmp, Oper);
	foreach (var b in buildings)
	{
		tree.UpdateLazy(posMap[b[0]], posMap[b[1] - 1], b[2]);
	}
	for (int i = 0; i < pos.Length; i++)
	{
		var h = tree.QueryLazy(posMap[pos[i]], posMap[pos[i]]);
		if (!isCheck && h != 0)
		{
			rslt.Add(pos[i], h);
			isCheck = true;
		}
		else if (i > 0 && h != lastHeight)
		{
			rslt.Add(pos[i], h);
		}
		lastHeight = h;
	}

	return rslt;
}
private int Oper(int i, int j)
{
	return Math.Max(i, j);
}
/// <summary>
/// 离散化
/// </summary>
/// <param name="positions"></param>
/// <returns></returns>
private Tuple<Dictionary<int, int>, int[]> Discretization(int[][] positions)
{
	var tmp = new Dictionary<int, int>();
	var posMap = new Dictionary<int, int>();
	List<int> posArray = new List<int>();
	foreach (var item in positions)
	{
		var key = item[0];  // 左边界
		if (tmp.ContainsKey(key))
		{
			tmp[key] = tmp[key] + 1;
		}
		else
		{
			tmp.Add(key, 1);
		}
		key = item[1] - 1;  // 右边界 - 1
		if (tmp.ContainsKey(key))
		{
			tmp[key] = tmp[key] + 1;
		}
		else
		{
			tmp.Add(key, 1);
		}
		key = item[1];      // 右边界提供Query
		if (tmp.ContainsKey(key))
		{
			tmp[key] = tmp[key] + 1;
		}
		else
		{
			tmp.Add(key, 1);
		}
	}
	foreach (var item in tmp.Keys)
	{
		posArray.Add(item);
	}
	posArray.Sort();    // X轴要排序
	for (int i = 0; i < posArray.Count; i++)
	{
		posMap[posArray[i]] = i;
	}

	return new Tuple<Dictionary<int, int>, int[]>(posMap, posArray.ToArray());
}
posted @ 2022-04-30 23:09  wesson2019  阅读(12)  评论(0编辑  收藏  举报