
😎풀이
- 이벤트 배열을 생성하여 건물의 시작점, 높이, 진입점 여부를 기록한다.
- 기록된 이벤트 배열을 정렬한다.
2-1. X 좌표를 최우선적으로 비교하여 오름차 순으로 정렬한다.
2-2. X 좌표가 같다면 높이를 기준으로 정렬한다.
2-3. 이 때, 건물의 진입점이라면 높이를 내림차 순으로 정렬한다.
2-4. 건물의 진입점이 아니라면 높이를 오름차 순으로 정렬한다.
Map
자료구조를 선언한다.
- 이벤트 배열을 순회한다.
4-1. 진입점일 경우 해당 건물의 높이에 1을 더한다.
4-2. 진입점이 아닐 경우 해당 건물 높이에 1을 뺀다.
4-3. 매 순회 시 건물의 최대 높이를 기록하고, 현재 순회중인 건물 높이와 비교하여 다를 경우 result
에 현재 건물의 X 좌표와 높이를 추가한다.
4-4. 최대 높이를 갱신한다.
result
를 반환한다.
function getSkyline(buildings: number[][]): number[][] {
type Event = [x: number, height: number, isEntering: boolean];
let events: Event[] = [];
for (const [left, right, height] of buildings) {
events.push([left, height, true]);
events.push([right, height, false]);
}
events.sort((a, b) => {
const [aX, aY, aE] = a;
const [bX, bY, bE] = b;
if (aX !== bX) return aX - bX;
if (aE && bE) return bY - aY;
if (!aE && !bE) return aY - bY;
return aE ? -1 : 1;
});
let result: number[][] = [];
let heights: Map<number, number> = new Map();
let prevMaxHeight = 0;
for (const [x, height, isEntering] of events) {
if (isEntering) {
heights.set(height, (heights.get(height) || 0) + 1);
} else {
if (heights.get(height) === 1) {
heights.delete(height);
} else {
heights.set(height, heights.get(height)! - 1);
}
}
let currentMaxHeight = Math.max(...heights.keys(), heights.size)
if (currentMaxHeight !== prevMaxHeight) {
result.push([x, currentMaxHeight]);
prevMaxHeight = currentMaxHeight;
}
}
return result;
}