K Closest Points to Origin

Given an array of points where each point is represented as points[i] = [xi, yi] on the X-Y plane and an integer k, return the k closest points to the origin (0, 0).

The distance between two points on the X-Y plane is the Euclidean distance, defined as: 

sqrt( (x2 – x1)2 + (y2 – y1)2 )

Note: You can return the k closest points in any order, driver code will sort them before printing.

Examples:

Input: k = 2, points[] = [[1, 3], [-2, 2], [5, 8], [0, 1]]
Output: [[-2, 2], [0, 1]]
Explanation: The Euclidean distances from the origin are:
Point (1, 3) = sqrt(10)
Point (-2, 2) = sqrt(8)
Point (5, 8) = sqrt(89)
Point (0, 1) = sqrt(1)
The two closest points to the origin are [-2, 2] and [0, 1].
Input: k = 1, points = [[2, 4], [-1, -1], [0, 0]]
Output: [[0, 0]]
Explanation: The Euclidean distances from the origin are:
Point (2, 4) = sqrt(20)
Point (-1, -1) = sqrt(2)
Point (0, 0) = sqrt(0)
The closest point to origin is (0, 0).

Constraints:

  • 1 <= k <= points.size() <= 105
  • -104 <= xi, yi <= 104

Approach 01:

#include <vector>
#include <queue>
#include <cmath>

class Solution {
public:
    std::vector<std::vector<int>> kClosest(std::vector<std::vector<int>>& points, int k) {
        // Max heap to store k closest points
        std::priority_queue<std::pair<int, std::pair<int, int>>> maxHeap;
        int totalPoints = points.size();
        
        for (int i = 0; i < totalPoints; i++) {
            int x = points[i][0], y = points[i][1];
            int squaredDistance = (x * x) + (y * y);
            
            // Push the point into the max heap
            maxHeap.push({squaredDistance, {x, y}});
            
            // Maintain only k closest points in the heap
            if (maxHeap.size() > k) {
                maxHeap.pop();
            }
        }
        
        // Extract k closest points
        std::vector<std::vector<int>> closestPoints;
        while (!maxHeap.empty()) {
            closestPoints.push_back({maxHeap.top().second.first, maxHeap.top().second.second});
            maxHeap.pop();
        }
        
        return closestPoints;
    }
};
import heapq

class Solution:
    def kClosest(self, points, k):
        # Max heap to store k closest points
        maxHeap = []
        
        for x, y in points:
            squaredDistance = (x * x) + (y * y)
            
            # Push the point into the max heap (negative distance for max heap behavior)
            heapq.heappush(maxHeap, (-squaredDistance, x, y))
            
            # Maintain only k closest points in the heap
            if len(maxHeap) > k:
                heapq.heappop(maxHeap)
        
        # Extract k closest points
        closestPoints = [[x, y] for _, x, y in maxHeap]
        return closestPoints

Time Complexity:

  • Inserting Points into the Heap:

    Each of the \( n \) points is inserted into the heap, taking \( O(\log k) \) time per insertion. This results in \( O(n \log k) \) time.

  • Maintaining Heap Size:

    We remove the largest element from the heap whenever its size exceeds \( k \), which takes \( O(\log k) \) per operation.

  • Extracting k Closest Points:

    Extracting \( k \) elements from the heap takes \( O(k \log k) \) time.

  • Total Time Complexity:

    The overall complexity is \( O(n \log k) \).

Space Complexity:

  • Heap Storage:

    We maintain a max heap of size at most \( k \), requiring \( O(k) \) space.

  • Output Storage:

    The output vector stores \( k \) points, contributing \( O(k) \) space.

  • Total Space Complexity:

    The overall space complexity is \( O(k) \).

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top