给出一个线段集合,集合中每个线段都有一个起点和一个终点,再给一个线段,问该线段是否可以被集合完全覆盖。
/**
* 给出一个线段集合,集合中每个线段都有一个起点和一个终点,再给一个线段,问该点段是否可以被集合完全覆盖。
*
* 先过滤不相交的线段,再逐步缩小范围。
*
*/
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);
}
}