Skip to content

Latest commit

 

History

History
115 lines (98 loc) · 2.73 KB

the-skyline-problem.md

File metadata and controls

115 lines (98 loc) · 2.73 KB

Code

type point struct {
	x       int
	height  int
	isStart bool
}

func getSkyline(buildings [][]int) [][]int {
	// make a slice to store all points
	pointList := make([]point, 0)

	// Populate pointList
	for _, building := range buildings {
		start, end, height := building[0], building[1], building[2]
		p1 := point{start, height, true}
		p2 := point{end, height, false}

		pointList = append(pointList, p1, p2)
	}

	// Sort list based on specified conditions
	sort.Slice(pointList, func(i, j int) bool {
		// pick lower of x value, if same follow below rules
		if pointList[i].x > pointList[j].x {
			return false
		} else if pointList[i].x < pointList[j].x {
			return true
		} else {
			// If both are start points, pick one with higher height
			// If both are end, pick one with lower height
			// If both are at same point and either one is start, return the one which is start
			if pointList[i].isStart && pointList[j].isStart {
				if pointList[i].height > pointList[j].height {
					return true
				} else if pointList[i].height < pointList[j].height {
					return false
				} else {
					return pointList[i].isStart
				}
			} else if !pointList[i].isStart && !pointList[j].isStart {
				if pointList[i].height > pointList[j].height {
					return false
				} else if pointList[i].height < pointList[j].height {
					return true
				} else {
					return pointList[i].isStart
				}
			} else {
				return pointList[i].isStart
			}
		}
	})

	// Maintain a map to keep track of points
	heightQueue := make(map[int]int, 0)
	maxInQueue := 0
	heightQueue[0] = 1

	sol := [][]int{}

	// Iterate through points
	for _, point := range pointList {

		// If point is starting of building, add to queue
		// If the point is taller than all existing ones, append to solution and modify height
		if point.isStart {
			if _, ok := heightQueue[point.height]; ok {
				heightQueue[point.height] += 1
			} else {
				heightQueue[point.height] = 1
			}

			if point.height > maxInQueue {
				sol = append(sol, []int{point.x, point.height})
				maxInQueue = point.height
			}
		} else {
			// If point is ending of building, decrement or delte value from map
			val := heightQueue[point.height]

			if val == 1 {
				delete(heightQueue, point.height)
			} else {
				heightQueue[point.height] -= 1
			}

			// If point was the sole maximum, compute new max and append to solution
			if point.height == maxInQueue {
				if _, ok := heightQueue[point.height]; !ok {
					max := 0
					for key, _ := range heightQueue {
						if key > max {
							max = key
						}
					}
					maxInQueue = max
					sol = append(sol, []int{point.x, maxInQueue})
				}
			}

		}
	}

	return sol

}

Solution in mind