问题描述
二维平面上有许多点p(x , y),按照彼此之间的欧式距离进行分为若干个集合。若点p1(x1, y1)与点p(x2, y2)之间距离小于d,则认为二者是邻居。
算法思路
给数据集的点进行编号,顺序遍历这些点,找出当前点的邻居,记住已经遍历过的点,直到遍历完数据集
代码实现
import java.util.ArrayList;
import java.util.List;
import static java.awt.geom.Point2D.distance;
public class Leetcode {
// 聚类算法,列表a是节点列表,d是每个集合内任意两点的最短距离
public static List<List> spe(List<Node> a, int d) {
List<List> r = new ArrayList<>();
boolean[] visited = new boolean[a.size()];
if (a.size() == 0) return r;
for (int i = 0; i < a.size(); i++) {
if (visited[a.get(i).index] == false)
dfs(a, i, r, visited, new ArrayList<>(), d);
}
return r;
}
static void dfs(List<Node> a, int i, List<List> r, boolean[] visited, List<Node> cur, int d) {
Node current = a.get(i);
cur.add(current);
visited[current.index] = true;
boolean hasNeighbor = false;
for (int j = 0; j < a.size(); j++) {
if (j != i && visited[a.get(j).index] == false && distance(current.x, current.y, a.get(j).x, a.get(j).y) <= d) {
hasNeighbor = true;
dfs(a, j, r, visited, cur, d);
}
}
if (hasNeighbor == false) {
r.add(new ArrayList(cur));
}
}
static class Node {
double x; // x坐标
double y; // y坐标
int index; // 在数据集的编号
public Node(double[] x, int index) {
this.x = x[0];
this.y = x[1];
this.index = index;
}
}
public static void main(String[] args) {
double[] point1 = {1.0, 2.0};
double[] point2 = {2.0, 3.0};
Node node1 = new Node(point1, 0);
Node node2 = new Node(point2, 1);
double[] point3 = {11.0, 22.0};
double[] point4 = {14.0, 22.0};
Node node3 = new Node(point3, 2);
Node node4 = new Node(point4, 3);
List<Node> t = new ArrayList<>();
t.add(node1);
t.add(node2);
t.add(node3);
t.add(node4);
List<List> r = spe(t, 10);
System.out.println(r);
}
}