K closest points to a given point

本文介绍了一种快速查找平面上给定点周围最近K个点的算法。该算法采用类似快速排序的方法进行分区,并通过递归缩小搜索范围来提高效率。适用于大规模数据集场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

K closest points to a given point (x, y). N is in millions and K is few hundreds.

package array;

import java.util.*;

public class KClosestPoints {
//http://www.1point3acres.com/bbs/forum.php?mod=viewthread&tid=172475&extra=page%3D2%26filter%3Dsortid%26sortid%3D311%26searchoption%5B3046%5D%5Bvalue%5D%3D2%26searchoption%5B3046%5D%5Btype%5D%3Dradio%26sortid%3D311
	int dist(Point p1, Point p2) {
		int dx = p1.x - p2.x;
		int dy = p1.y - p2.y;
		return dx * dx + dy * dy;
	}

	int qs(Point[] arr, Point target, int start, int end) {
		Point pivot = arr[end]; // end out
		int targetdist = dist(pivot, target);
		while (start < end) {
			while (start < end && dist(arr[start], target) < targetdist) {
				start++;
			}
			arr[end] = arr[start]; // into end
			while (start < end && dist(arr[end], target) > targetdist) {
				end--;
			}
			arr[start] = arr[end]; // into start, end empty
		}
		arr[end] = pivot; // into end
		return end;
	}

	public Point[] kn(Point[] arr, Point target, int k) {
		int mid = -1;
		int low = 0;
		int high = arr.length - 1;
		do {
			mid = qs(arr, target, low, high);
			if (mid < k) {
				low = mid + 1;
			} else if (mid > k) {
				high = mid - 1;
			}
		} while (mid != k);
		return Arrays.copyOfRange(arr, 0, k);
	}

	public static void main(String[] args) {
		KClosestPoints s = new KClosestPoints();
		Point p1 = new Point(0, 0);
		Point p2 = new Point(1, 0);
		Point p3 = new Point(0, 1);
		Point p4 = new Point(0, 2);
		Point p5 = new Point(2, 0);
		Point p6 = new Point(1, 2);
		Point p7 = new Point(2, 1);
		Point[] points = { p1, p2, p3, p4, p5, p6, p7 };
		for (Point p : s.kn(points, new Point(3, 0), 5))
			System.out.println("x:"+p.x+" y:"+p.y);
	}

}

class Point {
	int x;
	int y;

	public Point(int x, int y) {
		this.x = x;
		this.y = y;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值