【问题描述】
给定一组报告,其中的每个报告设置了一个开始时间si和结束时间fi。设计与实现一个算法,对这组报告分配最少数量的教室,使得这些报告能无冲突的举行。
1 package org.xiu68.exp.exp8; 2 3 import java.util.ArrayList; 4 import java.util.Comparator; 5 6 public class Exp8_1 { 7 8 public static void main(String[] args) { 9 // TODO Auto-generated method stub 10 ArrayList<Report> reports=new ArrayList<>(); 11 reports.add(new Report(7,10)); 12 reports.add(new Report(8,11)); 13 reports.add(new Report(9,13)); 14 reports.add(new Report(12,14)); 15 reports.add(new Report(13,15)); 16 intervalPartition(reports); 17 } 18 19 public static void intervalPartition(ArrayList<Report> reports){ 20 reports.sort(new comp()); //按开始时间对报告进行排序 21 22 //不使用优先队列 23 //ArrayList<Integer> classrooms=new ArrayList<>(); 24 //classrooms.get(i)表示第i间教室的报告的结束时间 25 //classrooms.add(reports.get(0).endTime); 26 27 //使用优先队列 28 PriorityQueue<ClassRoom> classrooms=new PriorityQueue<>(); 29 //首先为第1份报告分配教室 30 classrooms.add(new ClassRoom(reports.get(0).endTime)); 31 32 for(int i=1;i<reports.size();i++){ 33 //不使用优先队列 34 /*boolean flag=false; //是否找到教室 35 for(int j=0;j<classrooms.size();j++){ 36 if(reports.get(i).startTime>=classrooms.get(j)){ //找到教室 37 classrooms.set(j, reports.get(i).endTime); 38 flag=true; 39 break; 40 } 41 } 42 if(flag==false){ //找不到教室,另分配一间教室 43 classrooms.add(reports.get(i).endTime); 44 }*/ 45 46 //使用优先队列 47 if(reports.get(i).startTime>=classrooms.getMin().endTime){ //找到教室 48 //教室来了新报告后需要调整使用教室的结束时间 49 classrooms.setFirstElement(new ClassRoom(reports.get(i).endTime)); 50 }else{ 51 classrooms.add(new ClassRoom(reports.get(i).endTime)); //找不到教室,新开辟一间教室 52 } 53 54 } 55 System.out.println("最少需要 "+classrooms.size()+" 间教室"); 56 } 57 58 } 59 60 class Report{ 61 public int startTime; //开始时间 62 public int endTime; //结束时间 63 64 public Report(int startTime, int endTime) { 65 super(); 66 this.startTime = startTime; 67 this.endTime = endTime; 68 } 69 } 70 71 class ClassRoom implements Comparable<ClassRoom>{ 72 public int endTime; 73 public ClassRoom(int endTime){ 74 this.endTime=endTime; 75 } 76 @Override 77 public int compareTo(ClassRoom o) { 78 // TODO Auto-generated method stub 79 if(endTime>o.endTime) 80 return 1; 81 else 82 return -1; 83 } 84 } 85 class comp implements Comparator<Report>{ 86 @Override 87 //按开始时间排序报告的比较方法 88 public int compare(Report r1, Report r2) { 89 // TODO Auto-generated method stub 90 if(r1.startTime>r2.startTime) 91 return 1; 92 else 93 return -1; 94 } 95 }
1 package org.xiu68.exp.exp8; 2 3 import java.util.Comparator; 4 import java.util.NoSuchElementException; 5 6 7 public class PriorityQueue<E extends Comparable<E>> { 8 private E[] heap; 9 private int size; 10 private Comparator<E> comp; 11 12 @SuppressWarnings("unchecked") 13 public PriorityQueue(){ 14 heap=(E[])new Comparable[5]; 15 } 16 public PriorityQueue(Comparator<E> comp){ 17 this(); 18 this.comp=comp; 19 } 20 21 @SuppressWarnings("unused") 22 private int compare(E e1,E e2){ 23 if(comp==null) 24 return e1.compareTo(e2); 25 else 26 return comp.compare(e1, e2); 27 } 28 29 @SuppressWarnings("unchecked") 30 public void add(E element){ 31 //如果添加元素后数组已满,则先扩容再加入 32 if(++size==heap.length){ 33 E[] e=(E[])new Comparable[heap.length*2]; 34 System.arraycopy(heap, 0, e, 0, size); 35 heap=e; 36 } 37 heap[size-1]=element; 38 adjust(); 39 } 40 41 //设置堆顶元素,需要从堆顶开始调整堆 42 public void setFirstElement(E element){ 43 if(size<=0){ 44 throw new NoSuchElementException(); 45 } 46 heap[0]=element; 47 adjustFromIndex(0); 48 } 49 public void adjustFromIndex(int i){ 50 //由于从序号为0开始存储,需要加这段 51 if(i==0 && size>1){ 52 int j; 53 if(size>2){ //大于等于3个元素 54 j=(compare(heap[i+1],heap[i+2])>0?i+1:i+2); //j为左右孩子的最小者的下标 55 }else{ //只有两个元素 56 j=i+1; 57 } 58 if(compare(heap[i],heap[j])>0){ //父结点大于子结点,交换值 59 E temp=heap[i]; 60 heap[i]=heap[j]; 61 heap[j]=temp; 62 } 63 adjustFromIndex(j); 64 } 65 66 int parent=i; 67 int child=2*i; 68 while(child<=size-1){ 69 //child<size-1表示parent左右孩子都存在 70 //child存放左右孩子最大者数组下标 71 if(child<size-1 && compare(heap[child],heap[child+1])>0){ 72 child+=1; 73 } 74 if(compare(heap[parent],heap[child])<=0){ //父结点大于子结点,停止调整 75 break; 76 }else{ 77 E temp=heap[parent]; 78 heap[parent]=heap[child]; 79 heap[child]=temp; 80 parent=child; 81 child=2*parent; 82 } 83 } 84 } 85 //从新加入元素开始调整堆 86 public void adjust(){ 87 int newElement=size-1; 88 int parentElement; 89 while(newElement>0){ //还没有调整到根结点 90 parentElement=newElement/2; //根结点为newElement/2向下取整 91 92 //如果父结点小于等于子结点则不需要调整 93 if(compare(heap[parentElement],heap[newElement])<=0){ 94 break; 95 } 96 //交换父结点与子结点的值 97 E temp=heap[parentElement]; 98 heap[parentElement]=heap[newElement]; 99 heap[newElement]=temp; 100 newElement=parentElement; 101 } 102 } 103 //获取最小元素 104 public E getMin(){ 105 if(size==0){ 106 throw new NoSuchElementException(); 107 } 108 return heap[0]; 109 } 110 //返回队列大小 111 public int size(){ 112 return size; 113 } 114 }