Find the K Closest Points to Origin using Priority Queue


In this problem, we will find the K nearest point from the origin in the 2D plane from the given N points.

We can use the standard Euclidean distance formula to calculate the distance between the origin and each given point. After that, we can store the points with distance in the array, sort the array according to the distance, and take the first K points.

However, we can also use the priority queue to store the 2D points according to their distance from the origin. After that, we can deque the queue for K times.

Problem statement − We have given N points into the 2D plane. We need to find the K nearest point from the origin of the plane.

Note − Consider the Euclidean distance as the distance between the origin and the given point of the plane.

Sample examples

Input

points = {{2, -2}, {-5, 1}, {2, 1}, {0, 3}, {6, 0}, {5, 5}, {4, 9}}, K = 4

Output

{2,1} {2,-2} {0,3} {-5,1}

Explanation − Here is the Euclidean distance of each point from the origin.

  • (2, −2) −> sqrt(8)

  • (−5, 1) −> sqrt(26)

  • (2, 1) −> sqrt(5)

  • (0, 3) −> sqrt(9)

  • (6, 0) −> sqrt(36)

  • (5, 5) −> sqrt(50)

  • (4, 9) −> sqrt(97)

So, the 4 nearest points are {2,1} {2,−2} {0,3} {−5,1}.

Input

points = {{1, 2}, {2, 1}, {-2, 1}, {1, -2}} K = 2

Output

{1, 2}, {2, 1}

Explanation − The distance of all points from the origin is the same. So, we can print any 2 points as an output.

Input

points = {{1, 3}, {6, 7}, {1, 1}, {1, 0}} K = 4

Output

{1, 0}, {1, 1}, {1, 3}, {6, 7}

Explanation − The K is equal to the given points. So, we need to print all points.

Approach 1

In this approach, we will use the sort() method to sort the array. Also, we will use the comparator function to sort the points according to their distance from the origin. After that, we print the first K element of the sorted array.

Algorithm

Step 1 − Use the sort() method to sort the list and pass the distComparator() function as a third parameter.

Step 2 − Define the distComparator() function to compare the distance of given points. The function takes the p and q pairs as a parameter.

Step 2.1 − Take the distance of point p from the origin and store it in the dist_p.

Step 2.2 − Take the distance of the point q from the origin and store it in the dist_q variable.

Step 2.3 − Return true if dist_p is less than dist_q. Otherwise, return false.

Step 3 − Traverse the array, and print first K points of the array.

Example

#include <bits/stdc++.h>
using namespace std;

bool distComparator(const pair<int, int> &p, const pair<int, int> &q) {
    int dist_p = p.first * p.first + p.second * p.second;
    int dist_q = q.first * q.first + q.second * q.second;
    return dist_p < dist_q;
}
vector<pair<int, int>> findKPoints(vector<pair<int, int>> points, int n, int k) {
    vector<pair<int, int>> res_points;
    sort(points.begin(), points.end(), distComparator);
    // Get the first K points
    for (int p = 0; p < k; p++)     {
        res_points.push_back({points[p].first, points[p].second});
    }
    return res_points;
}
int main() {
    int k = 4, n = 7;
    vector<pair<int, int>> points{{2, -2}, {-5, 1}, {2, 1}, {0, 3}, {6, 0}, {5, 5}, {4, 9}};
    vector<pair<int, int>> res = findKPoints(points, n, k);
    cout << "The " << k << " closest points from origin are - ";
    for (int p = 0; p < k; p++) {
        cout << "{" << res[p].first << "," << res[p].second << "} ";
    }
    return 0;
}

Output

The 4 closest points from origin are - {2,1} {2,-2} {0,3} {-5,1}

Time complexity − O(NlogN) for sorting the array.

Space complexity − O(N) to sort the array.

Approach 2

In this approach, we will use the priority queue to insert the points. Also, we will use the comparator function with the priority queue to store the points based on their shortest distance from the origin.

Algorithm

Step 1 − Define the ‘res_points’ list of pair to store the K nearest points.

Step 2 − Define the priority queue. Here, the ‘pair<int, int>’ represents the use priority queue to store the pair of integers. The ‘vector<pair<int, int>>’ represents the use of the vector to store the pairs. Also, we used the ‘cmp’ function with the priority queue.

Step 3 − Define the cmp() function to compare the Euclidian distance of two points from the origin.

Step 3.1 − Return the boolean value based on the distance of point a larger than the distance of point b from the origin.

Step 4 − Insert each element of the array into the priority queue.

Step 5 − Pop up the first K elements from the queue and store them into the res_points list.

Step 6 − Return the res_points list of points.

Example

#include <bits/stdc++.h>
using namespace std;

vector<pair<int, int>> findKPoints(vector<pair<int, int>> points, int n, int k) {
    vector<pair<int, int>> res_points;
    // Custom comparator to compare points based on their distance from the origin
    auto cmp = [](const pair<int, int>& a, const pair<int, int>& b) {
        return (a.first * a.first + a.second * a.second) > (b.first * b.first + b.second * b.second);
    };
    // Use the custom comparator in the priority_queue
    priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(cmp)> p_que(cmp);
    for (int p = 0; p < n; p++) {
        // Inserting points in a queue
        p_que.push(points[p]);
    }
    // Get first K points
    while (k--) {
        auto temp = p_que.top();
        res_points.push_back(temp);
        p_que.pop();
    }
    return res_points;
}
int main() {
    int k = 4, n = 7;
    vector<pair<int, int>> points{{2, -2}, {-5, 1}, {2, 1}, {0, 3}, {6, 0}, {5, 5}, {4, 9}};
    vector<pair<int, int>> res = findKPoints(points, n, k);
    cout << "The " << k << " closest points from origin are - ";
    for (int p = 0; p < k; p++) {
        cout << "{" << res[p].first << "," << res[p].second << "} ";
    }
    return 0;
}

Output

The 4 closest points from origin are - {2,1} {2,-2} {0,3} {-5,1}

Time complexity − O(N*logN) to insert N elements into the priority queue. Here, N is the total number of points.

Space complexity − O(N) to store points in the priority queue.

The priority queue uses the heap data structure. So, it takes only O(logN) time to insert and delete elements. Both approaches take the same memory and time. However, the second approach is more efficient as it uses the heap data structure.

Updated on: 02-Aug-2023

100 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements