Find the nearest dot in a 2D space

前端 未结 4 1272
庸人自扰
庸人自扰 2021-02-19 21:17

Yesterday I read a problem which can be translated into the following problem with slight modification:

The coordinate of a dot is expressed by (x, y) in a 2D space.

4条回答
  •  深忆病人
    2021-02-19 22:04

    I have come out with a solution in O(logN) if the dots are sorted on x coordinate.

    It uses a divide-and-conquer approach. I divide the dots array based on their x coordinate in the 2D space.

    Consider the 2D case.

    Assume each dot is expressed in the following data structure:

    class Point {
        public float getX();
        public float getY();
    }
    

    We have two inputs: dot array ARRAY, and another dot D.

    Initially, we would like to partition ARRAY into two parts: those dots that are on the "left" of D, and those dots are on the "right" of D.

    int pivotIndex = partition(array, 0, array.length() - 1, d);
    

    After partition, the dots with index less than pivotIndex have x coordinate less than d.getX(); the dots with index equal or greater than pivotIndex have x coordinate equal or greater than d.getX().

    If all dots are on the left side of D, pivotIndex would be array.length() - 1. If all dots are on the right side of D, pivotIndex would be -1. If some dots are on the left of D and some dots are on the right of D, then pivotIndex would be between 0 and array.length() - 1. For dots having the same x coordinate as D, they are considered as on the "right" side.

    Now, the next step is to search the nearest dot on each partition:

    Point p1 = getNearestDot(array, 0, pivotIndex, d);
    Point p2 = getNearestDot(array, pivotIndex + 1, array.length() - 1, d);
    
    if (p1 == null) return p2;
    if (p2 == null) return p1;
    
    return nearer(p1, p2, d);
    

    It is possible that all the dots in the ARRAY are on the left side of D, then p2 would be null in this case. Similarly, if all dots in the ARRAY are on the right side of D, then p1 would be null.

    The algorithm of getNearestDot works as below:

    // Find the nearest dot in array[low...high] inclusive which is closest to point d 
    Point getNearestDot(Point[] array, int low, int high, Point d) {
        if (low > high)
            return null;
        if (low == high)
            return array[low];
    
        int middle = low + (high - low) >> 1;
        Point p1 = getNearestDot(array, low, middle, d);
        Point p2 = getNearestDot(array, middle + 1, high, d);
    
        if (p1 == null) return p2;
        if (p2 == null) return p1;
    
        return nearer(p1, p2, d);
    } 
    

    And finally, the function nearer(p1, p2, d) is to return either p1 or p2, whose distance to d is shorter.

提交回复
热议问题