问题一:求不被支配的点
对于平面上的两个点p1=(x1, y1)和p2=(x2,y2),如果x1<=x2且y1<=y2,则p2支配p1,给定平面上的n个点,请设计算法求其中没有被任何其他点支配的点
问题思路
- 将平面上的点按照横坐标的平均值mid进行划分(也可以使用中位数,这样时间复杂度更稳定),横坐标小于等于mid的点,放到points_left中,横坐标大于mid的点,放到points_right中
- 处理子问题points_right和points_left,得到set_right和set_left
- 找到points_right中纵坐标的最大值max_y
- 遍历points_left中所有点,将set_left中纵坐标小于等于max_y的点删去
- 返回set_left和set_right的并
错误思路(想尽量减小时间复杂度,没有将points_left进行处理,导致错误),下面的代码也是错误思路的代码,懒得改了😄:
将平面上的点按照横坐标的平均值mid进行划分(也可以使用中位数,这样时间复杂度更稳定),横坐标小于等于mid的点,放到points_left中,横坐标大于mid的点,放到points_right中
- 处理子问题points_right,得到set_right
- 找到points_right中纵坐标的最大值max_y
- 遍历points_left中所有点,将set_left中纵坐标小于等于max_y的点删去
- 返回set_left和set_right的并
/*
这里的代码有问题了,
*/
import java.util.HashSet;
import java.util.Set;
public class FindPointSet {
public Set<Point> pointSet = new HashSet<Point>();
public void Find(Set<Point> points) {
if (points == null) return;
else if (points.size() <= 1) {
pointSet.addAll(points);
return ;
}
int numX = 0;
for (Point point : points) {
numX += point.getX();
}
//System.out.println(points.size());
int mid = numX / points.size();
Set<Point> pointsLeft = new HashSet<Point>();
Set<Point> pointsRight = new HashSet<Point>();
for (Point point : points) {
if (point.getX() <= mid) pointsLeft.add(point);
else pointsRight.add(point);
}
Find(pointsRight);
//假定这是比最小的纵坐标还小的一个数
int maxY = -1;
for (Point point : pointsRight) {
if(point.getY() > maxY)
maxY = point.getY();
}
for (Point point : pointsLeft) {
if (point.getY() <= maxY)
pointSet.add(point);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Point point1 = new Point(1, 2);
Point point2 = new Point(3, 4);
Point point3 = new Point(6, 0);
Point point4 = new Point(2, 8);
Point point5 = new Point(4, 6);
Point point6 = new Point(5, 5);
Set<Point> points = new HashSet<Point>();
points.add(point1);
points.add(point2);
points.add(point3);
points.add(point4);
points.add(point5);
points.add(point6);
FindPointSet findPointSet = new FindPointSet();
findPointSet.Find(points);
for (Point point : findPointSet.pointSet) {
System.out.println(point);
}
}
}
class Point{
private int x, y;
Point(int x, int y){
this.x = x;
this.y = y;
}
int getX(){
return this.x;
}
int getY(){
return this.y;
}
@Override
public String toString() {
String string = "(" + this.x + "," + this.y +")" + "\n";
return string;
}
}
时间复杂度分析
T
(
n
)
=
2
T
(
n
/
2
)
+
θ
(
n
)
T(n) = 2T(n / 2) + \theta(n)
T(n)=2T(n/2)+θ(n)
由Master定理得,时间复杂度是
O
(
n
l
g
n
)
O(nlgn)
O(nlgn)