算法学习——分治算法(二)

问题一:求不被支配的点

对于平面上的两个点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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值