线段覆盖

给出一个线段集合,集合中每个线段都有一个起点和一个终点,再给一个线段,问该线段是否可以被集合完全覆盖。

/**
 * 给出一个线段集合,集合中每个线段都有一个起点和一个终点,再给一个线段,问该点段是否可以被集合完全覆盖。
 * 
 * 先过滤不相交的线段,再逐步缩小范围。
 *
 */
public class RangeCover {
	private ArrayList<Range> temp = new ArrayList<Range>();
	
	public boolean cover(Range ro, ArrayList<Range> rb){
		assert(ro != null);
		assert(rb != null && rb.size() != 0);
		System.out.println("current ro is : " + ro.begin + "    " + ro.end);
		System.out.println(rb.size());
		for(Range item : rb){
			System.out.println(item.begin + " + " + item.end);
		}
		System.out.println("===============================");
		if(rb.size() == 0){
			
			return false;
		}
		float min = rb.get(0).begin;
		float max = rb.get(0).end;
		//排除不相交,同时记录最大范围
		for(Range item : rb){
			if((item.begin <= ro.begin) && (item.end >= ro.end)){
				return true;
			}
			if((item.begin > ro.end) || (item.end < ro.begin)){
				temp.add(item);
			}
			if(item.begin < min){
				min = item.begin;
			}
			if(item.end > max){
				max = item.end;
			}
		}
		if((ro.begin < min) || (ro.end > max)){
			return false;
		}else{
			rb.removeAll(temp);
			temp.clear();
		}
		//this progress decides the time complexity, the average is O(n) I think
		float maxEnd = ro.begin;
		float minBegin = ro.end;
		for(Range item : rb){
			//如果包住起始点,注意要等于
			if(item.begin <= ro.begin){
				if(item.end > maxEnd){
					maxEnd = item.end;
				}
				temp.add(item);
			}	
			//如果包住结束点
			if(item.end >= ro.end){
				if(item.begin < minBegin){
					minBegin = item.begin;
				}
				temp.add(item);
			}
		}
		//如果有重叠,证明已覆盖
		if(minBegin <= maxEnd){
			return true;
		}else{
			rb.removeAll(temp);
			temp.clear();
			Range newRO = new Range(maxEnd, minBegin);
			return cover(newRO, rb);
		}
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Range ro1 = new Range(5, 12);
		Range ro2 = new Range(2, 8);
		Range ro3 = new Range(1, 3);
		Range ro4 = new Range(56, 78);
		Range ro5 = new Range(3, 12);
		Range ro6 = new Range(6, 8);
		Range ro7 = new Range(4, 18);
		Range ro8 = new Range(13, 14);
		Range ro9 = new Range(22, 88);
		Range ro10 = new Range(9, 16);
		Range ro11 = new Range(24, 34);
		Range ro12 = new Range(96, 118);
		Range ro13 = new Range(4, 9);
		Range ro14 = new Range(17f, 23.0f);
		
		ArrayList<Range> rb = new ArrayList<Range>();
		rb.add(ro1);
		rb.add(ro2);
		rb.add(ro3);
		rb.add(ro4);
		rb.add(ro5);
		rb.add(ro6);
		rb.add(ro7);
		rb.add(ro8);
		rb.add(ro9);
		rb.add(ro10);
		rb.add(ro11);
		rb.add(ro12);
		rb.add(ro13);
		rb.add(ro14);

		Range ro = new Range(8, 266);
		RangeCover cover = new RangeCover();
		boolean b = cover.cover(ro, rb);
		System.out.println(b);
	}

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值