K Closest Points to Origin
MediumThe problem
Each point is [x, y] on a flat plane. Return the k points that are closest to the origin (0, 0), using normal straight-line distance. The points in the answer can be in any order.
- Example 1Input: points = [[1, 3], [-2, 2]], k = 1Output: [[-2, 2]]
(-2, 2) is closer to the origin than (1, 3).
- Example 2Input: points = [[3, 3], [5, -1], [-2, 4]], k = 2Output: [[3, 3], [-2, 4]]
Squared distances are 18, 26 and 20, so the two smallest belong to (3, 3) and (-2, 4).
- 1 ≤ k ≤ points.length ≤ 100,000
- -10,000 ≤ x, y ≤ 10,000
- The answer is guaranteed to be unique apart from its order
Write it in Go. Try for about 20 minutes on paper first, then open one hint at a time.
Try it here
Write Go. Common packages like fmt and sort are imported for you. Keep the function name and inputs the same.
Hints, one at a time
Nudge
You do not need exact distances — comparing squared distances is enough. Keep only the k best.
The idea
Max-heap of size k keyed by squared distance; evict the farthest when size > k.
Target: O(n log k) time
Go function shape
func kClosest(points [][]int, k int) [][]intReference solution
Tested with go test. Try it yourself first, then compare.
// KClosest keeps a MAX-heap of the k closest points so far (keyed by squared distance, no square root needed).
// The root is the farthest of the k, the one to evict when a closer point arrives.
type pointHeap [][3]int // {squared distance, x, y}
func (h pointHeap) Len() int { return len(h) }
func (h pointHeap) Less(i, j int) bool { return h[i][0] > h[j][0] }
func (h pointHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *pointHeap) Push(x any) { *h = append(*h, x.([3]int)) }
func (h *pointHeap) Pop() any {
old := *h
x := old[len(old)-1]
*h = old[:len(old)-1]
return x
}
func KClosest(points [][]int, k int) [][]int {
h := &pointHeap{}
for _, p := range points {
heap.Push(h, [3]int{p[0]*p[0] + p[1]*p[1], p[0], p[1]})
if h.Len() > k {
heap.Pop(h)
}
}
out := make([][]int, 0, k)
for _, e := range *h {
out = append(out, []int{e[1], e[2]})
}
return out
}