23. K Closest Points to Origin
β GFG solution to the K Closest Points to Origin problem: find k nearest points to origin using efficient selection algorithms like nth_element, sorting, and heaps. π
The problem can be found at the following link: π Question Link
π§© Problem Description
Given an integer k and an array of points points[][], where each point is represented as points[i] = [xi, yi] on the X-Y plane, 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:
distance = sqrt((x2 - x1)Β² + (y2 - y1)Β²)
You can return the k closest points in any order. The driver code will print them in sorted order. Test cases are generated such that there will be a unique answer.
π Examples
Example 1
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].Example 2
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 \le k \le \text{points.size()} \le 10^5$
$-3 \times 10^4 \le x_i, y_i \le 3 \times 10^4$
β
My Approach
The optimal approach uses STL's nth_element algorithm for efficient partial sorting:
nth_element with Lambda Comparator
Calculate Distance:
For each point, the squared Euclidean distance from origin is
xΒ² + yΒ².We avoid computing square roots since comparing squared distances preserves ordering.
Partial Sorting with nth_element:
Use
nth_elementto partition the array such that the k smallest elements (by distance) are placed before position k.The algorithm rearranges elements so that:
Elements before position k are β€ the element at position k
Elements after position k are β₯ the element at position k
No full sorting is required, making it more efficient than complete sort.
Custom Comparator:
Lambda function compares squared distances:
a[0]*a[0]+a[1]*a[1] < b[0]*b[0]+b[1]*b[1]This ensures points are ordered by their proximity to origin.
Extract Result:
Return the first k elements from the rearranged array.
These k elements are guaranteed to be the k closest points.
π Time and Auxiliary Space Complexity
Expected Time Complexity: O(n) on average, where n is the number of points. The
nth_elementalgorithm uses introselect (a hybrid of quickselect and heapselect), which has linear average-case performance. In the worst case, it can be O(n log n), but this is rare with good pivot selection.Expected Auxiliary Space Complexity: O(1), as
nth_elementperforms in-place partitioning without requiring additional data structures. Only a constant amount of space is used for variables and the lambda function.
π§βπ» Code (C++)
class Solution {
public:
vector<vector<int>> kClosest(vector<vector<int>>& points, int k) {
nth_element(points.begin(), points.begin() + k, points.end(),
[](auto& a, auto& b) { return a[0]*a[0]+a[1]*a[1] < b[0]*b[0]+b[1]*b[1]; });
return vector<vector<int>>(points.begin(), points.begin() + k);
}
};β Code (Java)
class Solution {
public ArrayList<ArrayList<Integer>> kClosest(int[][] points, int k) {
Arrays.sort(points, (a, b) -> (a[0]*a[0] + a[1]*a[1]) - (b[0]*b[0] + b[1]*b[1]));
ArrayList<ArrayList<Integer>> res = new ArrayList<>();
for (int i = 0; i < k; i++)
res.add(new ArrayList<>(Arrays.asList(points[i][0], points[i][1])));
return res;
}
}π Code (Python)
class Solution:
def kClosest(self, points, k):
points.sort(key=lambda x: x[0]**2 + x[1]**2)
return points[:k]π§ Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: π¬ Any Questions?. Let's make this learning journey more collaborative!
β If you find this helpful, please give this repository a star! β
πVisitor Count
Last updated