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:
-
C++
-
Python
#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) \).