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());
}