Find K nearest Points to Point P in 2-dimensional plane

后端 未结 9 1711
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-31 04:27

Source: AMAZON INTERVIEW QUESTION

Given a point P and other N points in two dimensional space, find K points

9条回答
  •  一生所求
    2021-01-31 05:01

    Solution 1

    private List nearestKPoint_1(List list, final Point center, int k) {
        List ans = new ArrayList<>();
        PriorityQueue maxHeap = new PriorityQueue<>(k + 1, new Comparator() {
            @Override
            public int compare(Point o1, Point o2) {
                return distance(center, o2) - distance(center, o1);
            }
        });
        for (Point p : list) {
            maxHeap.offer(p);
            if (maxHeap.size() > k) {
                maxHeap.poll();
            }
        }
        Iterator i = maxHeap.iterator();
        while (i.hasNext()) {
            ans.add(i.next());
        }
        return ans;
    }
    
    public int distance(Point p1, Point p2) {
        return (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y);
    }
    
    static class Point {
        int x;
        int y;
    
        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
    
            Point point = (Point) o;
    
            if (x != point.x) return false;
            return y == point.y;
        }
    
        @Override
        public int hashCode() {
            int result = x;
            result = 31 * result + y;
            return result;
        }
    }
    

    Solution 2

    private List nearestKPoint_2(List list, final Point center, int k) {
        List ans = new ArrayList<>();
        Distance[] nums = new Distance[list.size()];
        for (int i = 0; i < nums.length; i++) {
            nums[i] = new Distance(distance(center, list.get(i)), i);
        }
        quickSelect(nums, k);
        for (int i = 0; i < k; i++) {
            ans.add(list.get(nums[i].i));
        }
        return ans;
    }
    
    private void quickSelect(Distance[] nums, int k) {
        int start = 0, end = nums.length - 1;
        while (start < end) {
            int p = partition(nums, start, end);
            if (p == k) {
                return;
            } else if (p < k) {
                start = p + 1;
            } else {
                end = p - 1;
            }
        }
    }
    private int partition(Distance[] nums, int start, int end) {
        Distance pivot = nums[start];
        int i = start, j = end + 1;
        while (true) {
            while (i < end && nums[++i].compareTo(pivot) < 0);
            while (j > start && nums[--j].compareTo(pivot) > 0);
            if (i >= j) {
                break;
            }
            swap(nums, i, j);
        }
        swap(nums, start, j);
        return j;
    }
    
    private void swap(Distance[] nums, int i, int j) {
        Distance tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
    
    class Distance implements Comparable {
        int d;
        int i;
    
        public Distance(int d, int i) {
            this.d = d;
            this.i = i;
        }
    
        @Override
        public int compareTo(Distance o) {
            return this.d - o.d;
        }
    }
    

提交回复
热议问题